Files
claude-scientific-skills/scientific-skills/edgartools/references/xbrl.md

374 lines
9.2 KiB
Markdown

# edgartools — XBRL Reference
## Table of Contents
- [Core Classes](#core-classes)
- [XBRL Class](#xbrl-class)
- [Statements Access](#statements-access)
- [XBRLS — Multi-Period Analysis](#xbrls--multi-period-analysis)
- [Facts Querying](#facts-querying)
- [Statement to DataFrame](#statement-to-dataframe)
- [Value Transformations](#value-transformations)
- [Rendering](#rendering)
- [Error Handling](#error-handling)
- [Import Reference](#import-reference)
---
## Core Classes
| Class | Purpose |
|-------|---------|
| `XBRL` | Parse single filing's XBRL |
| `XBRLS` | Multi-period analysis across filings |
| `Statements` | Access financial statements from single XBRL |
| `Statement` | Individual statement object |
| `StitchedStatements` | Multi-period statements interface |
| `StitchedStatement` | Multi-period individual statement |
| `FactsView` | Query interface for all XBRL facts |
| `FactQuery` | Fluent fact query builder |
---
## XBRL Class
### Creating an XBRL Object
```python
from edgar.xbrl import XBRL
# From a Filing object (most common)
xbrl = XBRL.from_filing(filing)
# Via filing method
xbrl = filing.xbrl() # returns None if no XBRL
# From directory
xbrl = XBRL.from_directory("/path/to/xbrl/files")
# From file list
xbrl = XBRL.from_files(["/path/instance.xml", "/path/taxonomy.xsd"])
```
### Core Properties
```python
xbrl.statements # Statements object
xbrl.facts # FactsView object
# Convert all facts to DataFrame
df = xbrl.to_pandas()
# Columns: concept, value, period, label, ...
```
### Statement Methods
```python
stmt = xbrl.get_statement("BalanceSheet")
stmt = xbrl.get_statement("IncomeStatement")
stmt = xbrl.get_statement("CashFlowStatement")
stmt = xbrl.get_statement("StatementOfEquity")
# Render with rich formatting
rendered = xbrl.render_statement("BalanceSheet")
rendered = xbrl.render_statement("IncomeStatement", show_percentages=True, max_rows=50)
print(rendered)
```
---
## Statements Access
```python
statements = xbrl.statements
balance_sheet = statements.balance_sheet()
income_stmt = statements.income_statement()
cash_flow = statements.cash_flow_statement()
equity = statements.statement_of_equity()
comprehensive = statements.comprehensive_income()
```
All return `Statement` objects or `None` if not found.
---
## XBRLS — Multi-Period Analysis
```python
from edgar import Company
from edgar.xbrl import XBRLS
company = Company("AAPL")
# Get multiple filings (use amendments=False for clean stitching)
filings = company.get_filings(form="10-K", amendments=False).head(3)
# Stitch together
xbrls = XBRLS.from_filings(filings)
# Access stitched statements
stitched = xbrls.statements
income_stmt = stitched.income_statement()
balance_sheet = stitched.balance_sheet()
cashflow = stitched.cashflow_statement()
equity_stmt = stitched.statement_of_equity()
comprehensive = stitched.comprehensive_income()
```
### StitchedStatements Parameters
All methods accept:
- `max_periods` (int) — max periods to include (default: 8)
- `standard` (bool) — use standardized concept labels (default: True)
- `use_optimal_periods` (bool) — use entity info for period selection (default: True)
- `show_date_range` (bool) — show full date ranges (default: False)
- `include_dimensions` (bool) — include segment data (default: False)
- `view` (str) — `"standard"`, `"detailed"`, or `"summary"` (overrides `include_dimensions`)
```python
# Standard view (default)
income = stitched.income_statement()
# Detailed view with dimensional breakdowns
income_detailed = stitched.income_statement(view="detailed")
# Convert to DataFrame (periods as columns)
df = income.to_dataframe()
```
---
## Facts Querying
### FactsView — Starting a Query
```python
facts = xbrl.facts
# Query by concept
revenue_q = facts.by_concept("Revenue")
revenue_q = facts.by_concept("us-gaap:Revenue", exact=True)
# Query by label
rd_q = facts.by_label("Research", exact=False)
# Query by value range
large_q = facts.by_value(min_value=1_000_000_000)
small_q = facts.by_value(max_value=100_000)
range_q = facts.by_value(min_value=100, max_value=1000)
# Query by period
period_q = facts.by_period(start_date="2023-01-01", end_date="2023-12-31")
```
### FactQuery — Fluent Chaining
```python
# Chain multiple filters
query = (xbrl.facts
.by_concept("Revenue")
.by_period(start_date="2023-01-01")
.by_value(min_value=1_000_000))
# Execute
facts_list = query.execute() # List[Dict]
facts_df = query.to_dataframe() # DataFrame
first_fact = query.first() # Dict or None
count = query.count() # int
# Filter by statement type
income_facts = xbrl.facts.by_statement("IncomeStatement")
```
### Analysis Methods on FactsView
```python
# Pivot: concepts as rows, periods as columns
pivot = facts.pivot_by_period(["Revenue", "NetIncomeLoss"])
# Time series for a concept
revenue_ts = facts.time_series("Revenue") # pandas Series
# Convert all to DataFrame
all_df = facts.to_dataframe()
```
---
## Statement to DataFrame
### Statement.to_dataframe()
```python
statement = xbrl.statements.income_statement()
# Raw mode (default) — exact XML values
df_raw = statement.to_dataframe()
# Presentation mode — matches SEC HTML display
df_presentation = statement.to_dataframe(presentation=True)
# Additional options
df = statement.to_dataframe(
include_dimensions=True, # include segment breakdowns (default: True)
include_unit=True, # include unit column (USD, shares)
include_point_in_time=True # include point-in-time column
)
```
### Columns in output
- Core: `concept`, `label`, period date columns
- Metadata (always): `balance`, `weight`, `preferred_sign`
- Optional: `dimension`, `unit`, `point_in_time`
### Get Concept Value
```python
revenue = statement.get_concept_value("Revenue")
net_income = statement.get_concept_value("NetIncomeLoss")
```
---
## Value Transformations
edgartools provides two layers of values:
**Raw Values (default):** Values exactly as in XML instance document. Consistent across companies, comparable to SEC CompanyFacts API.
**Presentation Values (`presentation=True`):** Transformed to match SEC HTML display. Cash flow outflows shown as negative. Good for investor-facing reports.
```python
statement = xbrl.statements.cash_flow_statement()
# Raw: dividends paid appears as positive
df_raw = statement.to_dataframe()
# Presentation: dividends paid appears as negative (matches HTML)
df_pres = statement.to_dataframe(presentation=True)
```
### Metadata columns explain semantics:
- `balance`: debit/credit from schema
- `weight`: calculation weight (+1.0 or -1.0)
- `preferred_sign`: presentation hint (+1 or -1)
### When to use each:
| Use Raw | Use Presentation |
|---------|-----------------|
| Cross-company analysis | Matching SEC HTML display |
| Data science / ML | Investor-facing reports |
| Comparison with CompanyFacts API | Traditional financial statement signs |
---
## Rendering
```python
# Render single statement
rendered = xbrl.render_statement("BalanceSheet")
print(rendered) # Rich formatted output
# Render Statement object
stmt = xbrl.statements.income_statement()
rendered = stmt.render()
rendered = stmt.render(show_percentages=True, max_rows=50)
print(rendered)
# Multi-period render
stitched_stmt = xbrls.statements.income_statement()
rendered = stitched_stmt.render(show_date_range=True)
print(rendered)
```
---
## Advanced Examples
### Complex Fact Query
```python
from edgar import Company
from edgar.xbrl import XBRL
company = Company("MSFT")
filing = company.latest("10-K")
xbrl = XBRL.from_filing(filing)
# Query with multiple filters
results = (xbrl.facts
.by_concept("Revenue")
.by_value(min_value=50_000_000_000)
.by_period(start_date="2023-01-01")
.to_dataframe())
# Pivot analysis
pivot = xbrl.facts.pivot_by_period([
"Revenue",
"NetIncomeLoss",
"OperatingIncomeLoss"
])
```
### Cross-Company Comparison
```python
from edgar import Company
from edgar.xbrl import XBRL
companies = ["AAPL", "MSFT", "GOOGL"]
for ticker in companies:
company = Company(ticker)
filing = company.latest("10-K")
xbrl = XBRL.from_filing(filing)
if xbrl and xbrl.statements.income_statement():
stmt = xbrl.statements.income_statement()
revenue = stmt.get_concept_value("Revenue")
print(f"{ticker}: ${revenue/1e9:.1f}B")
```
---
## Error Handling
```python
from edgar.xbrl import XBRL, XBRLFilingWithNoXbrlData
try:
xbrl = XBRL.from_filing(filing)
except XBRLFilingWithNoXbrlData:
print("No XBRL data in this filing")
# Check availability
xbrl = filing.xbrl()
if xbrl is None:
print("No XBRL available")
text = filing.text() # fallback
# Check statement availability
if xbrl and xbrl.statements.income_statement():
income = xbrl.statements.income_statement()
df = income.to_dataframe()
```
---
## Import Reference
```python
# Core
from edgar.xbrl import XBRL, XBRLS
# Statements
from edgar.xbrl import Statements, Statement
from edgar.xbrl import StitchedStatements, StitchedStatement
# Facts
from edgar.xbrl import FactsView, FactQuery
from edgar.xbrl import StitchedFactsView, StitchedFactQuery
# Rendering & standardization
from edgar.xbrl import StandardConcept, RenderedStatement
# Utilities
from edgar.xbrl import stitch_statements, render_stitched_statement, to_pandas
```