Run3 sec 13f fund analysis aum stocks
[COLM'26] SkillLearnBench is the first benchmark for evaluating continual learning methods that automatically generate agent skills.
npx -y skills add cxcscmu/SkillLearnBench --skill run3_sec-13f-fund-analysis-aum-stocksAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
How to analyze a fund's AUM and stock count using accession_number, with proper filtering of options and deduplication. Covers Q1 (AUM) and Q2 (stock count).
SKILL.md
3.4 KB, 924 tokens by cl100k_base, as published. Nobody here has run it
Fund Analysis: AUM and Stock Count
Method 1: Use Built-in Scripts (Preferred and More Reliable)
# Check if analysis script exists and read its source
cat /root/2025-q3/scripts/one_fund_analysis.py 2>/dev/null
# Run it with the accession number
python /root/2025-q3/scripts/one_fund_analysis.py "<ACCESSION_NUMBER>" 2>/dev/null
Always prefer built-in scripts as they handle edge cases (option filtering, deduplication) correctly.
Method 2: Manual Analysis
Getting AUM
AUM might be in SUMMARYPAGE.tsv or can be computed from INFOTABLE:
import pandas as pd
# Check SUMMARYPAGE first
summary = pd.read_csv('/root/2025-q3/SUMMARYPAGE.tsv', sep='\t')
fund_summary = summary[summary['ACCESSION_NUMBER'] == accession]
print(fund_summary)
# Look for columns like TABLEENTRYTOTAL, TABLEVALUETOTAL, etc.
# Or compute from INFOTABLE
info = pd.read_csv('/root/2025-q3/INFOTABLE.tsv', sep='\t', low_memory=False)
fund_holdings = info[info['ACCESSION_NUMBER'] == accession]
aum = fund_holdings['VALUE'].sum() # VALUE is in thousands
print(f"AUM: ${aum * 1000:,.0f}") # or just report in thousands
Counting Stocks Held - CRITICAL FILTERING
The stock count must exclude options (PUT/CALL entries). The PUTCALL column may contain unexpected values.
# STEP 1: Inspect PUTCALL column thoroughly
fund_holdings = info[info['ACCESSION_NUMBER'] == accession]
print("PUTCALL unique values:", fund_holdings['PUTCALL'].unique())
print("PUTCALL value counts:")
print(fund_holdings['PUTCALL'].value_counts(dropna=False))
# STEP 2: Also inspect SSHPRNAMTTYPE
print("SSHPRNAMTTYPE unique values:", fund_holdings['SSHPRNAMTTYPE'].unique())
print(fund_holdings['SSHPRNAMTTYPE'].value_counts(dropna=False))
# STEP 3: Filter to only stock holdings (exclude PUT and CALL)
# Options have PUTCALL = "Put" or "Call" (check exact case/spelling)
# Stocks have PUTCALL as NaN or empty
stocks_only = fund_holdings[
~fund_holdings['PUTCALL'].isin(['Put', 'Call', 'PUT', 'CALL', 'put', 'call'])
| fund_holdings['PUTCALL'].isna()
]
# Alternative more robust: only keep rows where PUTCALL is NaN or whitespace
stocks_only = fund_holdings[
fund_holdings['PUTCALL'].isna() |
(fund_holdings['PUTCALL'].astype(str).str.strip().isin(['', 'nan', 'NaN', 'None']))
]
# STEP 4: Count unique stocks - may need to deduplicate by CUSIP
# Check if the scripts use unique CUSIPs or unique rows
num_stocks = stocks_only['CUSIP'].nunique()
print(f"Number of unique stocks (by CUSIP): {num_stocks}")
# Also check total rows vs unique CUSIPs
print(f"Total stock rows: {len(stocks_only)}")
print(f"Unique CUSIPs: {stocks_only['CUSIP'].nunique()}")
Important: Understanding How Scripts Count Stocks
The built-in script likely:
- Filters out PUT/CALL rows
- May also filter by SSHPRNAMTTYPE == "SH" (shares only, excluding principal "PRN")
- May deduplicate by CUSIP or CUSIP + other fields
- Read the script source to understand the exact logic
# If filtering to shares only:
stocks_sh = fund_holdings[
(fund_holdings['PUTCALL'].isna() | (fund_holdings['PUTCALL'].astype(str).str.strip() == '')) &
(fund_holdings['SSHPRNAMTTYPE'].astype(str).str.strip() == 'SH')
]
print(f"Shares-only count: {stocks_sh['CUSIP'].nunique()}")
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.