agentsclimarketplace

Holdings comparison

Skill cxcscmu/SkillLearnBench/skills/b1-one-shot-claude-sonnet-4-6/financial-analysis/holdings-comparison

Compare fund holdings between two quarters (Q2 vs Q3) to identify increased/decreased positions by dollar value or share count.From its SKILL.md

Install
npx -y skills add cxcscmu/SkillLearnBench --skill holdings-comparison

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

SKILL.md

2.9 KB, 814 tokens by cl100k_base, as published. Nobody here has run it

Holdings Comparison Skill

Overview

To compare holdings across quarters, load INFOTABLE for both quarters, filter by accession number, then compute the difference in VALUE or SSHPRNAMT.

Step-by-step

1. Get accession numbers for both quarters

import pandas as pd

q2_cover = pd.read_csv("/root/2025-q2/COVERPAGE.tsv", sep="\t", dtype=str)
q3_cover = pd.read_csv("/root/2025-q3/COVERPAGE.tsv", sep="\t", dtype=str)

q2_acc = q2_cover[q2_cover["FILINGMANAGER_NAME"].str.contains("berkshire", case=False, na=False)]["ACCESSION_NUMBER"].iloc[0]
q3_acc = q3_cover[q3_cover["FILINGMANAGER_NAME"].str.contains("berkshire", case=False, na=False)]["ACCESSION_NUMBER"].iloc[0]

2. Load holdings for both quarters

q2_info = pd.read_csv("/root/2025-q2/INFOTABLE.tsv", sep="\t", dtype=str)
q3_info = pd.read_csv("/root/2025-q3/INFOTABLE.tsv", sep="\t", dtype=str)

q2_holdings = q2_info[q2_info["ACCESSION_NUMBER"] == q2_acc].copy()
q3_holdings = q3_info[q3_info["ACCESSION_NUMBER"] == q3_acc].copy()

q2_holdings["VALUE"] = pd.to_numeric(q2_holdings["VALUE"], errors="coerce").fillna(0)
q3_holdings["VALUE"] = pd.to_numeric(q3_holdings["VALUE"], errors="coerce").fillna(0)

3. Merge and compute changes

# Aggregate by CUSIP (a fund may have multiple entries per stock for different share types)
q2_agg = q2_holdings.groupby("CUSIP")["VALUE"].sum().reset_index().rename(columns={"VALUE": "VALUE_Q2"})
q3_agg = q3_holdings.groupby("CUSIP")["VALUE"].sum().reset_index().rename(columns={"VALUE": "VALUE_Q3"})

merged = pd.merge(q2_agg, q3_agg, on="CUSIP", how="outer").fillna(0)
merged["CHANGE"] = merged["VALUE_Q3"] - merged["VALUE_Q2"]

# Top 5 increased positions
top5 = merged.sort_values("CHANGE", ascending=False).head(5)
print(top5[["CUSIP", "VALUE_Q2", "VALUE_Q3", "CHANGE"]])

4. Find top investors in a specific stock

# Find all funds holding a specific CUSIP in Q3
palantir_cusip = "69608A108"  # example
holders = q3_info[q3_info["CUSIP"] == palantir_cusip].copy()
holders["VALUE"] = pd.to_numeric(holders["VALUE"], errors="coerce").fillna(0)

# Aggregate by accession number and merge with fund names
holders_agg = holders.groupby("ACCESSION_NUMBER")["VALUE"].sum().reset_index()
holders_with_names = holders_agg.merge(q3_cover[["ACCESSION_NUMBER", "FILINGMANAGER_NAME"]], on="ACCESSION_NUMBER")
top3 = holders_with_names.sort_values("VALUE", ascending=False).head(3)
print(top3[["FILINGMANAGER_NAME", "VALUE"]])

Notes

  • Always aggregate by CUSIP before comparing (avoid double-counting from multiple lot entries)
  • VALUE is in thousands USD in all TSV files
  • New positions (not in Q2) will have VALUE_Q2 = 0
  • Closed positions will have VALUE_Q3 = 0; exclude from "increased" analysis

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.