# SEC 13F Fund Holdings Diff — What Big Funds Bought & Sold (`celestjux/celestjux-sec-13f-diff`) Actor

Quarter-over-quarter 13F diff, not a raw filing dump: NEW/EXIT/ADD/TRIM/UNCHANGED per position, plus a cross-fund 'most bought' summary. Berkshire, Bridgewater, Renaissance or any 13F filer by CIK or name. Official SEC EDGAR only, amendments and unit change handled.

- **URL**: https://apify.com/celestjux/celestjux-sec-13f-diff.md
- **Developed by:** [Celest Jux](https://apify.com/celestjux) (community)
- **Categories:** Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.20 / 1,000 position rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## SEC 13F Fund Holdings Diff — what the big funds bought and sold

**Not a raw filing dump — a quarter-over-quarter diff.** Other 13F actors give you the filing;
this one tells you what changed: one row per position with the action — **NEW, EXIT, ADD, TRIM,
UNCHANGED** — and the change in shares, value and portfolio weight, plus one cross-fund summary of
which securities the selected funds bought, exited, added to or trimmed the most. Pick any
institutional manager (Berkshire Hathaway, Bridgewater, Renaissance, Pershing Square… or any 13F
filer by CIK or name).

The kind of view WhaleWisdom sells as a $300–500/yr subscription — here it's pay per use, amendments
and the 2023 unit change included.

Built on official SEC endpoints only (`data.sec.gov` submissions + EDGAR archives), with a declared
User-Agent and at most 5 requests/second (half the SEC fair-access limit). No scraping of third-party
sites, no proxy.

> SEC EDGAR filings are US federal public records. **Not investment advice.** 13F data is delayed,
> incomplete by design (see Limits), and self-reported by the filers.

### What you get

One record per position (`recordType: "position"`):

| Field | Example | Notes |
|---|---|---|
| `managerCik`, `managerName` | `1067983`, `BERKSHIRE HATHAWAY INC` | |
| `period`, `prevPeriod` | `2026-06-30`, `2026-03-31` | quarter ends, ISO dates (`prevPeriod` null in holdings mode) |
| `filedDate`, `accessionNo` | `2026-08-14`, `0001193125-26-352200` | the filing the row comes from |
| `issuer`, `titleOfClass`, `cusip` | `APPLE INC`, `COM`, `037833100` | as filed; no ticker mapping in v1 |
| `putCall` | `null` / `PUT` / `CALL` | only with `includeOptions` |
| `sharesType` | `SH` | `PRN` = principal amount of notes |
| `action` | `ADD` | `NEW` / `EXIT` / `ADD` / `TRIM` / `UNCHANGED` (null in holdings mode) |
| `sharesNow`, `sharesPrev`, `sharesChange` | `227917808`, `227917808`, `0` | EXIT → `sharesNow` 0; NEW → `sharesPrev` 0 |
| `sharesChangePct` | `-12.5` | % of `sharesPrev`; null for NEW |
| `valueNowUsd`, `valuePrevUsd` | `65950296923`, `57843260493` | whole US dollars (pre-2023 filings converted from thousands) |
| `weightNowPct`, `weightPrevPct` | `22.0383`, `21.9856` | % of the manager's reported value that quarter |
| `valueUnitCorrected` | `false` | `true` when the filer used the wrong value unit and the actor fixed it (see Units) |
| `filingUrl` | `https://www.sec.gov/Archives/edgar/data/1067983/000119312526352200/0001193125-26-352200-index.htm` | |
| `scrapedAt` | `2026-09-27T07:41:49Z` | UTC |

One summary record per run (`recordType: "summary"`, when `summary` is on — the last item):
`period` (null if the managers' latest quarters differ), `managers` (cik, name, period, prevPeriod,
filing), `skippedManagers`, and `topNew`, `topExits`, `topAdds`, `topTrims` — each the top 20
securities by number of selected funds, then total value: `{cusip, issuer, putCall, fundsCount, totalValueUsd}`.
In holdings mode the summary has `topHeld` instead. The summary covers every position that passed
your filters, even when `maxItems` or the charge cap cut the position rows.

Missing values are `null`, never empty strings.

### Input examples

Berkshire Hathaway, latest quarter vs the one before:

```json
{ "managers": ["1067983"] }
```

What the famous investors newly bought, positions over $50M only:

```json
{ "preset": "famous_investors", "actions": ["NEW"], "minValueUsd": 50000000 }
```

One fund's current holdings and weights (by name):

```json
{ "managers": ["Bridgewater Associates"], "mode": "holdings" }
```

A specific quarter:

```json
{ "managers": ["1067983", "1350694"], "quarter": "2025Q4" }
```

### Inputs

- `managers` — CIKs (digits, e.g. `1067983`) or names. Names go through the EDGAR company search
  limited to 13F-HR filers (prefix match). A name that matches exactly one filer — ignoring case,
  punctuation and legal suffixes like Inc/LLC/L.P. — resolves; otherwise the run fails and lists the
  candidates, so you can pick a CIK. Example: `"Pershing Square"` → PERSHING SQUARE INC. (CIK 2026053);
  `"Capital"` → fails with 40+ candidates.
- `preset` — `famous_investors`: Berkshire Hathaway (1067983), Pershing Square Inc. (2026053),
  Scion Asset Management (1649339), Bridgewater Associates (1350694), Renaissance Technologies
  (1037389), Appaloosa (1656456), Third Point (1040273), Tiger Global (1167483), Duquesne Family
  Office (1536411), Baupost Group (1061768). Can be combined with `managers`.
- `quarter` — `2026Q2` = holdings at 2026-06-30 vs the most recent earlier 13F-HR, usually
  2026-03-31. Empty = each manager's latest filed quarter (managers can differ: Scion's last 13F is
  2025Q3). A skipped quarter or 13F-NT does not erase the previous available 13F-HR. An explicitly
  listed manager without the requested or any earlier 13F-HR fails the run; a preset member is
  skipped and listed under `skippedManagers` in the summary.
- `mode` — `diff` (default) or `holdings` (the quarter's positions only).
- `actions` — keep only these actions (diff mode).
- `minValueUsd` — drop positions worth less (current value; previous value for EXIT).
- `includeOptions` — include PUT/CALL rows (default off). 13F reports an option's underlying value,
  so options are excluded from weights too unless this is on.
- `summary` (default on), `maxItems` (default 5000), `maxTotalChargeUsd` (optional cap).

Invalid input (bad CIK, malformed or unfinished quarter, unknown field) fails the run with a clear
message — nothing is guessed.

### How the diff is built

- **Positions** are summed per (CUSIP, put/call, shares-or-principal) across all rows of the filing
  (big managers split one holding over many rows by sub-manager/discretion). Issuer and class come
  from the largest row. The class label is not part of the key, so a relabel like "COM" → "COM NEW"
  between quarters does not turn one holding into an EXIT + NEW.
- **Action** compares share counts: new key → NEW, gone → EXIT, more → ADD, fewer → TRIM, equal → UNCHANGED.
- **Amendments** (13F-HR/A): a RESTATEMENT replaces the quarter's report; NEW HOLDINGS amendments
  (typically positions revealed after confidential treatment expires) are added to it. Example:
  Berkshire's 2025Q1 NEW HOLDINGS amendment filed 2025-08-14 added D.R. Horton, Lennar and Nucor.
- **Units**: filings made before 2023-01-03 report value in thousands of dollars, later ones in
  dollars. Everything is converted to dollars, so diffs across the change (e.g. `2022Q4` vs `2022Q3`)
  have no ×1000 jumps. Some filers never switched: Duquesne Family Office and Baupost still report
  thousands on the new form (2026). The actor checks each filing's median implied share price
  (value ÷ shares): under $1 on a dollars-form filing means thousands (×1000 applied), over
  $10,000 on an old-form filing means it was already dollars. Such rows carry
  `valueUnitCorrected: true`, and the summary's `managers[].unitCorrections` says which filing and why.
- **Unit guard**: an extreme median needs at least five distinct ordinary-share CUSIPs before
  automatic correction. Smaller samples fail with an ambiguous-units error; one penny stock, a
  single expensive share, or a PRN/options-heavy filing is insufficient evidence for ×1000.
  Even larger all-penny-stock portfolios remain a heuristic limitation.
- **Weights** are shares of the quarter's total reported value (options excluded unless included).
- The run checks that the information-table sum equals the cover page's reported total and records
  any mismatch in the run's `last_run_summary` (key-value store).

### When to run it — the 13F calendar

Managers file within 45 days of quarter end: mid-**February** (Q4), mid-**May** (Q1),
mid-**August** (Q2), mid-**November** (Q3). A schedule on the 16th of those months (with `quarter`
empty) catches almost everyone's newest filing. Many big funds file on the last day.

### Pricing

Pay per event: **$0.0002 per position row** and **$0.01 per summary record**. Berkshire Hathaway's
latest diff is ~30 rows (~$0.016 with the summary); the 10-fund preset, all actions, is about 5,300
rows (~$1.07; Renaissance alone has ~3,779) — use `actions`, `minValueUsd` or
`maxTotalChargeUsd` to keep it small. With a charge cap the summary is reserved first, then rows
fill the rest; the run stops cleanly before going over.

### Limits

- 13F covers **long US-listed equity positions** (plus listed options and some convertibles) of
  managers with over $100M in such assets. No short positions, no cash, no non-US holdings,
  no bonds in general.
- Data is **45+ days old** when filed, and a snapshot of the last day of the quarter.
- Some positions are withheld under confidential treatment and appear later via amendments.
- CUSIP + issuer name only; ticker mapping is planned (optional OpenFIGI with your own key).
- Machine-readable 13F tables start mid-2013, so the earliest diffable quarter is 2013Q3.

### Reliability

- Sequential requests, max 5/second, User-Agent `CelestJux 13F Diff juxtapo.opus@gmail.com` on every call.
- SEC 403/429 → wait at least 10 s (honour a longer `Retry-After` up to 300 s), retry once, then
  the run fails with the URL. Network errors / 5xx → 3
  attempts with backoff, then fail with the URL.
- Rows are pushed only after every manager loaded: a failure leaves no half-finished dataset, and
  nothing is charged for it.

# Actor input Schema

## `managers` (type: `array`):

SEC CIKs (digits, e.g. 1067983 = Berkshire Hathaway) or manager names (EDGAR prefix search, e.g. 'Bridgewater Associates'). An ambiguous name fails and lists the matching filers.

## `preset` (type: `string`):

famous\_investors = Berkshire Hathaway, Pershing Square, Scion, Bridgewater, Renaissance, Appaloosa, Third Point, Tiger Global, Duquesne, Baupost. Combined with 'Managers' when both are set.

## `quarter` (type: `string`):

e.g. 2026Q2 = that quarter's holdings vs the quarter before. Empty = each manager's latest filed quarter.

## `mode` (type: `string`):

diff = one row per position with the change; holdings = the quarter's positions and weights only.

## `actions` (type: `array`):

Diff mode only. Empty = all.

## `minValueUsd` (type: `number`):

Drop positions worth less than this (current value; previous value for exits).

## `includeOptions` (type: `boolean`):

13F option rows report the underlying's value. Off = common stock, ETFs, notes only.

## `summary` (type: `boolean`):

Push one summary record: securities most bought / exited / added / trimmed across the selected funds.

## `maxItems` (type: `integer`):

Hard cap on position rows pushed.

## `maxTotalChargeUsd` (type: `number`):

Optional extra spending cap under the platform's own. The run stops cleanly before exceeding it.

## Actor input object example

```json
{
  "managers": [
    "1067983"
  ],
  "mode": "diff",
  "includeOptions": false,
  "summary": true,
  "maxItems": 5000
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "managers": [
        "1067983"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("celestjux/celestjux-sec-13f-diff").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "managers": ["1067983"] }

# Run the Actor and wait for it to finish
run = client.actor("celestjux/celestjux-sec-13f-diff").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "managers": [
    "1067983"
  ]
}' |
apify call celestjux/celestjux-sec-13f-diff --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,celestjux/celestjux-sec-13f-diff"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/X9hB6joWZvCdrOUr0/builds/5AABAtfYVCuXNxEdT/openapi.json
