Previous slide Next slide Toggle fullscreen Open presenter view
10-K · open10k.com
As-Filed Financial Statements at Scale
Line-Item Structure, Concept Identity, and a Path Toward Standardized XBRL Data
Tim Olsen · Gonzaga University
Northwest Accounting Research Group · Portland, OR · October 23, 2026
open10k.com · Experimental features: open10k-lab.pages.dev
5,372,616
distinct XBRL reporting elements in the SEC data, most of them registrant extensions
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
Pop quiz
You want ten years of Apple's income statement, exactly as Apple filed it , in Excel.
What does that cost you today?
A A data subscription
B An afternoon of copy-and-paste from EDGAR
C Nothing
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
Answer: C, as of this year
Before
Vendor data: costly, and it's the vendor's standardized interpretation, not the filing
Chychyla & Kogan (2015): material discrepancies between Compustat and the 10-K
Do-it-yourself: the SEC data sets are normalized tables, so one balance sheet cell sits at the intersection of all of them
open10k.com
What the registrant filed
Organized the way the registrant organized it
Every XBRL fiscal year
Free, no login
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
1
Constructing open10k.com
The engineering, briefly
One pipeline, one source of truth
SEC Financial Statement & Notes data2009 → today
→
Parquet~10 GB, queried in place with DuckDB
→
One Malloy semantic modelall accounting logic
→
Excel workbook + web pageper registrant
The model decides:
which filing supplies the row structure
how presentation and calculation linkbases become an indented hierarchy
which amount wins after a restatement (the most recently filed)
how dimensional facts (segments, geography, products) attach to their lines
No value is scraped, estimated, or re-keyed. Python only renders.
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
Two features that make it trustworthy, not just convenient
amber Visible concept substitution
Registrants retag unchanged lines (Apple's "Net sales" before ASC 606).
If two elements agree exactly in ≥ 2 overlapping periods, never disagree , and share sign and period type, the earlier element fills the gap.
The cell is shaded, and a Tag Aliases sheet lists the evidence.
✓ Arithmetic verification
Live Excel formulas test every subtotal against the registrant's own calculation linkbase, plus:
the balance sheet identity
the cash flow reconciliation
cross-statement ties
A failed check is written where a reader can trace it (Debreceny et al. 2010; Du et al. 2013).
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
What a reader sees: open10k.com/AAPL
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
8,268
workbooks · 6,383 companies · Forms 10-K, 20-F and 40-F
Paper: 8,245 workbooks, incl. 1,405 Form 20-F filers and 792 non-USD reporters. Site updated monthly; October 2026 figures shown.
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
2
What should a row be?
The accounting question that turned out harder than the engineering
Option 1: the most recent 10-K defines the rows
Adopt the labels, order and hierarchy of the latest annual report; fill backward.
It's what a reader of the current 10-K expects, and what open10k does by default.
But:
a line presented for years and then discontinued disappears , with its amounts
a line retagged in earlier years shows a truncated history, unless substitution catches it
a blank early cell usually means "reported under another element," not "not reported"
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
Breakdowns that don't add up
Listing every disaggregation under a line was unreadable: Apple's Net sales carried 5 segments, 3 countries and 6 product categories in one list.
Group by axis instead. But a group is only honest if it partitions its parent line.
Across 35 registrants, 1,314 groups
Result
From the notes, never articulating
226 of 616
On the face, articulating every year
197 → 254 of 698 once members must appear on the statement
Rule: show a group if its members sum to the parent in ≥ half the years; blank its members in years they don't.
A group that sums to one member nests under it (iPhone, iPad, Mac, Wearables → Products).
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
Live today: color-coded breakdowns
plain on the statement pink from the notes, adds up red doesn't add up, shown as filed
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
Option 2: the union of every line ever presented
For ten large registrants:
Row set
Rows added vs. current structure
Naive union of all line items ever presented
+59% to +129%
De-duplicated union
+18% to +54%
The naive union is mostly repetition. Of 935 extra line items:
132superseded elements, already folded in
178share a label with a current row
71no annual amounts at all
554genuinely discontinued
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
What still breaks, and the road not taken
Two problems persist
51 earlier lines still share a label with a current row. Same line restated, or a different item with the same caption (current vs. non-current Deferred revenue )? No numeric tolerance reliably separates them.
A line dropped from the face can live on in the notes , so it has amounts after its "last presented" year.
Option 3: a calculation-linkbase union
3,993 elements on 6,313 paths
34% of elements sit on more than one path
14% of current lines (EPS, share counts, equity movements) are in no calculation at all
75 of 242 placements disagree with presentation, often because the old tree is stale
→ use it as a check , not the layout
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
open10k.com
Visualizing Financial Statements
Six charts per company, the SEC data behind them, and what the odd cases teach
Tim Olsen · Gonzaga University
open10k.com · free, no login, 6,000+ public companies
Pop quiz
Altria earned $6.9B in FY2025.
How much did its shareholders' equity go up ?
A About $6.9B
B About $3B
C It went down
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
1
Six charts, one page
What a student sees on every company page
The six charts, and the question each answers
Income flow
A Sankey: where revenue went and what was left
Balance sheet
Two equal columns: what it owns vs. who has a claim, year by year
Cash waterfall
Beginning cash to ending cash, step by step
Sources & uses
The same year's cash, gross: every inflow vs. every outflow
Three statements connect
Net income → cash flow → balance sheet, linked on hover
Trend
Revenue, net income and operating cash flow, every fiscal year
Static SVG, no chart library. Every piece has a hover card with the filed lines it is made of.
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
The baseline: Apple's income flow
Product detail appears because iPhone + Mac + iPad + Wearables + Services add up to revenue. If they didn't, the node would stay whole.
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
Where each chart gets its numbers
Standardized (FAC) row~60 comparable concepts per filing: revenue, operating income, total assets…
+
As-filed lines, by XBRL tagiPhone, R&D, buybacks, depreciation… from the workbook
+
A residual "other" barso every group adds up to its filed total
The skeleton is the same for every company, so the chart always adds up
The detail is the company's own labels, used only when the parts foot to the total
Coverage (Oct 28, 2026): Sankey on 6,353 pages, balance sheet 6,482 , waterfall 6,060 , sources & uses 6,053 , connected 4,991
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
2
From eight files to one workbook
The SEC Financial Statement & Notes data, and the queries that read it
The data: eight files per period, keyed on the filing
Only the columns the queries read. Blue = key. Every file joins to sub on adsh, the accession number.
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
Four queries, and which files each one reads
Query
sub
num
pre
ren
cal
tag
dim
Produces
statements_annual -> workbook_all
●
●
●
●
●
●
●
every statement tab, Data (long) , breakdowns, Tag Aliases , footing checks
filing_reports -> links
●
●
●
an EDGAR link on every column and tab
tag_history -> changes
●
●
concept-change log (research)
FAC (fac_annual, fac_peers)
●
●
standardized section, chart skeletons, 14 peers
Three queries live in one Malloy model (sec_statements_timeseries.malloy); Python only renders
FAC is a separate public model (sec-fac-malloy ), one row per filing, ~60 concepts
Charts combine FAC totals with workbook_all lines by tag
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
Inside workbook_all: what each file decides
File
Decides
sub
which filings are in scope; the newest 10-K/20-F supplies the rows; fiscal year from period, not fy
ren
which reports are statements (menucat = 'S'), so amendments that only touch Part III are skipped
pre
row labels, order, indentation, and which axes appear on the face
cal
the calculation tree: subtotals and the footing checks
num
the values; when filings disagree, the most recently filed wins
tag
debit/credit and instant/duration, to test whether a retagged line is the same line
dim
segment, product and geography labels for breakdowns
One cell of Apple's income statement touches seven files. That is why "just download the SEC data" doesn't give students a statement.
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
Making it fast enough to run 8,000 times
Raw quarterly & monthly files374M num rows, 218M pre rows
→
Derived extractsnum and pre bucketed by cik % 256; dim → dim_kv; pre + ren → pre_reports
→
SQL compiled onceCIK substituted at build time
→
One workbooka few seconds
A single company's facts sit in one file , so DuckDB opens 1/256th of the data
The Malloy model stays the source of truth; the cached SQL is checked against it
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
3
Edge cases
Where the usual picture breaks, and what that teaches
A bank has no "cost of goods sold": JPMorgan
Revenue is net interest income + noninterest income ; there's no gross profit, so the flow goes straight to pre-tax income. The credit loss provision is the bank-specific cost.
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
A loss: Rivian
Gross profit is a sliver ($144M on $5.4B). Costs exceed it, so the chart stops at the operating loss . Labels like "SG&A (Note 2)" are Rivian's own, as filed.
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
Negative equity: Altria's balance sheet
A deficit can't be drawn as a band, so it sits hatched on top of the assets and the columns still balance. Year by year: equity of $12.8B in FY2016 turns negative from FY2021.
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
Answer: equity went down
Dividends ($7.0B ) plus buybacks ($1.0B ) exceeded net income ($6.9B ). Equity fell from −$2.2B to −$3.5B.
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
A question for students: Coca-Cola's cash waterfall
Net income of $13.1B, but operating cash of only $7.4B : a −$7.1B working-capital-and-other bar. What happened? Go to the 10-K and find out.
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
Cash for a company burning it: AMC
Operations are a use of cash here, not a source. AMC paid for operations and investment by drawing down cash and new financing.
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
A foreign filer: ASML (20-F, IFRS, euros)
No standardized row for most 20-F filers, so this Sankey is built from the filed income statement by tag , in the filer's currency. Positive other items flow into net income in green.
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
When the skeleton misfires: Boeing
"Operating expenses $8.0M , −100% Y/Y" can't be right for Boeing. The chart is only as good as the concept mapping underneath it. Every chart can be checked against the filed statement on the same page.
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
And when there's no chart at all
Taiwan Semiconductor (TSM)
20-F under IFRS with tags not yet mapped: no charts , only the filed statements and workbook.
Funds, trusts, SPACs
646 pages have neither the standardized section nor a Sankey: no income statement in the usual sense.
The lesson: a chart is a model of the statement. The filed statement, and the 10-K behind it, is always one click away.
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
Using it in class
read Pick a company students know; have them explain each Sankey node from the 10-K
compare Apple vs. JPMorgan: why does a bank have no gross profit?
puzzle Altria: how can a profitable company have negative equity?
investigate Coca-Cola's cash gap, or Boeing's suspicious bar: find the answer in the filing
verify Download the workbook; check that the chart's totals match the statement
Olsen · As-Filed Financial Statements and Visualizations · open10k.com
open10k.com/MO
Try it now: pick a ticker
open10k.com/TICKER · or browse open10k.com/companies
Tim Olsen · olsent@gonzaga.edu
Welcome. The talk has three parts: what we built, the accounting question that turned out to be harder than the engineering, and what this means for getting to standardized data.
Hook. Every one of these is a "name" a company chose for a number. Keep this number in mind: it is the reason standardized data is hard, and it comes back at the end.
Ask for a show of hands. Most people will say A or B. That was true until recently.
The XBRL mandate promised machine-readable, comparable data (Blankespoor, Miller & White 2014). Free to download; expensive to consume.
Compiled once to SQL and cached, with the CIK substituted at build time: a workbook in a few seconds.
Live page. A summary sentence, a download button, and the statements in a grid that keeps the workbook's outline.
The paper's figures are as of September 15. The site has had one monthly update since.
Each of these is a silent loss: the reader can't tell from the grid that anything is missing.
This shipped September 29. Apple's segment operating income doesn't foot because segments exclude unallocated costs, so it gets the red marker rather than being hidden.
Three parts: what the charts show, where the numbers come from (the SEC files and the queries that turn them into a workbook), and a tour of companies whose statements break the usual picture.
Hold the answer: it's on the "three statements connect" slide.
Rule in sankey.py: parts must add up to within 0.5% of the total, at most 8 parts. Otherwise show the total only.
FAC = Fundamental Accounting Concepts (Charles Hoffman's "Seattle Method"), the sec-fac-malloy model. Companies without a FAC row, mostly 20-F filers, get the Sankey only, built from the filed income statement.
txt holds text facts (policies, narrative); none of the workbook or chart queries read it. dim is parsed once into dim_kv (one row per axis=member pair) before the model sees it.
The fy field is unreliable: NVIDIA's 10-K for the year ended 2024-01-31 carries fy=2023. Fiscal years are derived from the period end date instead.
Known issue as of this build: the standardized operating-expense concept for Boeing's FY2025 looks wrong. Use it as a lesson in checking, or fix before presenting.