institutions update holdings
import os
import requests
import time
import polars as pl
from rich import print as rprint
In this example we assume that the periodic check from the "Latest Filings" endpoint indicates two institutions need updates:
- CIK '0001067983' (Warren Buffett at Berkshire)
- CIK '0001649339' (Michael Burry at Scion)
We will use the institution/Institutional Holdings endpoint to get their latest portfolio:
https://api.unusualwhales.com/docs#/operations/PublicApi.InstitutionController.holdings
uw_token = os.environ['UW_TOKEN']
headers = {'Accept': 'application/json, text/plain', 'Authorization': uw_token}
names_to_update = ['0001067983', '0001649339'] # From the periodic check
all_responses = {}
for name in names_to_update:
holdings_url = f'https://api.unusualwhales.com/api/institution/{name}/holdings'
institution_responses = []
for i in range(100):
holdings_params = {
'limit': 500,
'page': i, # Page numbers start at 0 per documentation
}
holdings_rsp = requests.get(holdings_url, headers=headers, params=holdings_params)
if (holdings_rsp.status_code == 200) and (len(holdings_rsp.json()['data']) > 0):
institution_responses.append(holdings_rsp.json()['data'])
time.sleep(1) # Rate limit
else:
break
all_responses[name] = institution_responses
Since there might be multiple pages worth of changes for any given institution, we need to "flatten" the data associated with each CIK that is now stored in the all_responses dictionary. Once the data has been "flattened" we can use a DataFrame tool (like polars) to create institution-specific dataframes that make it easy to visually summarize the latest holdings.
flat_responses = {}
for cik, list_of_lists in all_responses.items():
flat_list = [item for sublist in list_of_lists for item in sublist]
flat_responses[cik] = flat_list
dfs = {}
for cik, list_of_dicts in flat_responses.items():
raw_df = pl.DataFrame(list_of_dicts)
dfs[cik] = raw_df
Now that we have a our DataFrames prepared, let's do a spot-check against the Unusual Whales site to confirm that the responses from the API match the latest holdings:
berkshire_check_df = (
dfs['0001067983']
.select(
[
'ticker', 'full_name', 'perc_of_total', 'units', 'security_type'
]
)
.rename(
{
'ticker': 'Ticker',
'full_name': 'Name',
'perc_of_total': '% Portfolio',
'units': 'Shares Owned',
'security_type': 'Type',
}
)
)
berkshire_check_df # Spot check against https://unusualwhales.com/institutions/berkshire-hathaway-inc
Ticker | Name | % Portfolio | Shares Owned | Type |
---|---|---|---|---|
str | str | str | i64 | str |
"AAPL" | "APPLE" | "0.262408170722… | 300000000 | "Share" |
"AXP" | "AMERICAN EXPRE… | "0.154354649570… | 151610700 | "Share" |
"BAC" | "BANK OF AMERIC… | "0.118823501269… | 797683307 | "Share" |
"KO" | "COCA COLA" | "0.107906444338… | 400000000 | "Share" |
"CVX" | "CHEVRON" | "0.065574913437… | 118610534 | "Share" |
… | … | … | … | … |
"BATRK" | "LIBERTY MEDIA" | "0.000033415078… | 223645 | "Share" |
"LSXMK" | "LIBERTY MEDIA" | "0.000000000000… | 0 | "Share" |
"LSXMA" | "LIBERTY MEDIA" | "0.000000000000… | 0 | "Share" |
"FND" | "FLOOR & DECOR … | "0.000000000000… | 0 | "Share" |
"9210611D" | null | "0.000000000000… | 0 | "Share" |
scion_check_df = (
dfs['0001649339']
.select(
[
'ticker', 'full_name', 'perc_of_total', 'units', 'security_type'
]
)
.rename(
{
'ticker': 'Ticker',
'full_name': 'Name',
'perc_of_total': '% Portfolio',
'units': 'Shares Owned',
'security_type': 'Type',
}
)
)
scion_check_df # Spot check against https://unusualwhales.com/institutions/scion-asset-management-llc
Ticker | Name | % Portfolio | Shares Owned | Type |
---|---|---|---|---|
str | str | str | i64 | str |
"BABA" | "ALIBABA" | "0.163571853140… | 200000 | "Share" |
"JD" | "JD.COM" | "0.154138572503… | 500000 | "Share" |
"JD" | "JD.COM" | "0.154138572503… | 500000 | "Option" |
"BABA" | "ALIBABA" | "0.138136429977… | 168900 | "Option" |
"FOUR" | "SHIFT4 PAYMENT… | "0.102425081428… | 150000 | "Share" |
… | … | … | … | … |
"OLPX" | "OLAPLEX HOLDIN… | "0.018111282269… | 1000000 | "Share" |
"REAL" | "THEREALREAL" | "0.012099877941… | 500000 | "Share" |
"ACIC" | "AMERICAN COAST… | "0.008685708560… | 100000 | "Share" |
"HPP" | "HUDSON PACIFIC… | "0.000000000000… | 0 | "Share" |
"BCAB" | "BIOATLA" | "0.000000000000… | 0 | "Share" |
Perfect, our spot check looks good! We have correctly obtained
the new portfolios for Berkshire Hathaway Inc (CIK
0001067983
) and Scion Asset Management (CIK
0001649339
), which means this new data can be
stored according to your persistence solution.