mirror of
https://github.com/K-Dense-AI/claude-scientific-skills.git
synced 2026-03-29 07:43:46 +08:00
Support EdgarTools to access and analyze SEC Edgar filings, XBRL financial statements, 10-K, 10-Q, and 8-K reports
This commit is contained in:
274
scientific-skills/edgartools/references/ai-integration.md
Normal file
274
scientific-skills/edgartools/references/ai-integration.md
Normal file
@@ -0,0 +1,274 @@
|
||||
# edgartools — AI Integration Reference
|
||||
|
||||
## Table of Contents
|
||||
- [Installation](#installation)
|
||||
- [MCP Server Setup](#mcp-server-setup)
|
||||
- [MCP Tools Reference](#mcp-tools-reference)
|
||||
- [Built-in AI Features](#built-in-ai-features)
|
||||
- [Skills for Claude](#skills-for-claude)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
# Core library
|
||||
uv pip install edgartools
|
||||
|
||||
# For MCP server and Skills
|
||||
uv pip install "edgartools[ai]"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MCP Server Setup
|
||||
|
||||
The MCP server gives any MCP-compatible client (Claude Desktop, Cursor, Cline, Continue.dev) direct access to SEC data.
|
||||
|
||||
### Option 1: uvx (Recommended — zero install)
|
||||
|
||||
Add to your MCP config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"edgartools": {
|
||||
"command": "uvx",
|
||||
"args": ["--from", "edgartools[ai]", "edgartools-mcp"],
|
||||
"env": {
|
||||
"EDGAR_IDENTITY": "Your Name your.email@example.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you get "spawn uvx ENOENT" on macOS, use the full path: `which uvx`.
|
||||
|
||||
### Option 2: Python (when edgartools already installed)
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"edgartools": {
|
||||
"command": "python3",
|
||||
"args": ["-m", "edgar.ai"],
|
||||
"env": {
|
||||
"EDGAR_IDENTITY": "Your Name your.email@example.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
On Windows, use `python` instead of `python3`.
|
||||
|
||||
### Option 3: Docker
|
||||
|
||||
```dockerfile
|
||||
FROM python:3.12-slim
|
||||
RUN pip install "edgartools[ai]"
|
||||
ENV EDGAR_IDENTITY="Your Name your.email@example.com"
|
||||
ENTRYPOINT ["python", "-m", "edgar.ai"]
|
||||
```
|
||||
|
||||
```bash
|
||||
docker build -t edgartools-mcp .
|
||||
docker run -i edgartools-mcp
|
||||
```
|
||||
|
||||
### Verify Setup
|
||||
|
||||
```bash
|
||||
python -m edgar.ai --test
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MCP Tools Reference
|
||||
|
||||
### edgar_company
|
||||
Get company profile, financials, recent filings, and ownership in one call.
|
||||
|
||||
| Parameter | Description |
|
||||
|-----------|-------------|
|
||||
| `identifier` | Ticker, CIK, or company name (required) |
|
||||
| `include` | Sections: `profile`, `financials`, `filings`, `ownership` |
|
||||
| `periods` | Number of financial periods (default: 4) |
|
||||
| `annual` | Annual vs quarterly (default: true) |
|
||||
|
||||
Example prompts:
|
||||
- "Show me Apple's profile and latest financials"
|
||||
- "Get Microsoft's recent filings and ownership data"
|
||||
|
||||
### edgar_search
|
||||
Search for companies or filings.
|
||||
|
||||
| Parameter | Description |
|
||||
|-----------|-------------|
|
||||
| `query` | Search keywords (required) |
|
||||
| `search_type` | `companies`, `filings`, or `all` |
|
||||
| `identifier` | Limit to specific company |
|
||||
| `form` | Filter by form type (e.g., `10-K`, `8-K`) |
|
||||
| `limit` | Max results (default: 10) |
|
||||
|
||||
### edgar_filing
|
||||
Read filing content or specific sections.
|
||||
|
||||
| Parameter | Description |
|
||||
|-----------|-------------|
|
||||
| `accession_number` | SEC accession number |
|
||||
| `identifier` + `form` | Alternative: company + form type |
|
||||
| `sections` | `summary`, `business`, `risk_factors`, `mda`, `financials`, or `all` |
|
||||
|
||||
Example prompts:
|
||||
- "Show me the risk factors from Apple's latest 10-K"
|
||||
- "Get the MD&A section from Tesla's most recent annual report"
|
||||
|
||||
### edgar_compare
|
||||
Compare companies side-by-side or by industry.
|
||||
|
||||
| Parameter | Description |
|
||||
|-----------|-------------|
|
||||
| `identifiers` | List of tickers/CIKs |
|
||||
| `industry` | Industry name (alternative to identifiers) |
|
||||
| `metrics` | Metrics to compare (e.g., `revenue`, `net_income`) |
|
||||
| `periods` | Number of periods (default: 4) |
|
||||
|
||||
### edgar_ownership
|
||||
Insider transactions, institutional holders, or fund portfolios.
|
||||
|
||||
| Parameter | Description |
|
||||
|-----------|-------------|
|
||||
| `identifier` | Ticker, CIK, or fund CIK (required) |
|
||||
| `analysis_type` | `insiders`, `institutions`, or `fund_portfolio` |
|
||||
| `days` | Lookback for insider trades (default: 90) |
|
||||
| `limit` | Max results (default: 20) |
|
||||
|
||||
---
|
||||
|
||||
## Built-in AI Features
|
||||
|
||||
These work without the `[ai]` extra.
|
||||
|
||||
### .docs Property
|
||||
|
||||
Every major object has searchable API docs:
|
||||
|
||||
```python
|
||||
from edgar import Company
|
||||
|
||||
company = Company("AAPL")
|
||||
company.docs # Full API reference
|
||||
company.docs.search("financials") # Search specific topic
|
||||
|
||||
# Also available on:
|
||||
filing.docs
|
||||
filings.docs
|
||||
xbrl.docs
|
||||
statement.docs
|
||||
```
|
||||
|
||||
### .to_context() Method
|
||||
|
||||
Token-efficient output for LLM context windows:
|
||||
|
||||
```python
|
||||
company = Company("AAPL")
|
||||
|
||||
# Control detail level
|
||||
company.to_context(detail='minimal') # ~100 tokens
|
||||
company.to_context(detail='standard') # ~300 tokens (default)
|
||||
company.to_context(detail='full') # ~500 tokens
|
||||
|
||||
# Hard token limit
|
||||
company.to_context(max_tokens=200)
|
||||
|
||||
# Also available on:
|
||||
filing.to_context(detail='standard')
|
||||
filings.to_context(detail='minimal')
|
||||
xbrl.to_context(detail='standard')
|
||||
statement.to_context(detail='full')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Skills for Claude
|
||||
|
||||
Skills teach Claude to write better edgartools code by providing patterns and best practices.
|
||||
|
||||
### Install for Claude Code (auto-discovered)
|
||||
|
||||
```python
|
||||
from edgar.ai import install_skill
|
||||
install_skill() # installs to ~/.claude/skills/edgartools/
|
||||
```
|
||||
|
||||
### Install for Claude Desktop (upload as project knowledge)
|
||||
|
||||
```python
|
||||
from edgar.ai import package_skill
|
||||
package_skill() # creates edgartools.zip
|
||||
# Upload the ZIP to a Claude Desktop Project
|
||||
```
|
||||
|
||||
### Skill Domains
|
||||
|
||||
| Domain | What It Covers |
|
||||
|--------|----------------|
|
||||
| **core** | Company lookup, filing search, API routing, quick reference |
|
||||
| **financials** | Financial statements, metrics, multi-company comparison |
|
||||
| **holdings** | 13F filings, institutional portfolios |
|
||||
| **ownership** | Insider transactions (Form 4), ownership summaries |
|
||||
| **reports** | 10-K, 10-Q, 8-K document sections |
|
||||
| **xbrl** | XBRL fact extraction, statement rendering |
|
||||
|
||||
### When to Use Which
|
||||
|
||||
| Goal | Use |
|
||||
|------|-----|
|
||||
| Ask Claude questions about companies/filings | MCP Server |
|
||||
| Have Claude write edgartools code | Skills |
|
||||
| Both | Install both — they complement each other |
|
||||
|
||||
---
|
||||
|
||||
## Filing to Markdown for LLM Processing
|
||||
|
||||
```python
|
||||
company = Company("NVDA")
|
||||
filing = company.get_filings(form="10-K").latest()
|
||||
|
||||
# Export to markdown for LLM analysis
|
||||
md = filing.markdown(include_page_breaks=True)
|
||||
|
||||
with open("nvidia_10k_for_analysis.md", "w") as f:
|
||||
f.write(md)
|
||||
|
||||
print(f"Saved {len(md)} characters")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**"EDGAR_IDENTITY environment variable is required"**
|
||||
Add your name and email to the `env` section of your MCP config. The SEC requires identification.
|
||||
|
||||
**"Module edgar.ai not found"**
|
||||
Install with AI extras: `uv pip install "edgartools[ai]"`
|
||||
|
||||
**"python3: command not found" (Windows)**
|
||||
Use `python` instead of `python3` in MCP config.
|
||||
|
||||
**MCP server not appearing in Claude Desktop**
|
||||
1. Check config file location for your OS
|
||||
2. Validate JSON syntax
|
||||
3. Restart Claude Desktop completely
|
||||
4. Run `python -m edgar.ai --test` to verify
|
||||
|
||||
**Skills not being picked up**
|
||||
1. Verify: `ls ~/.claude/skills/edgartools/`
|
||||
2. For Claude Desktop, upload as ZIP to a Project
|
||||
3. Skills affect code generation, not conversational responses
|
||||
268
scientific-skills/edgartools/references/companies.md
Normal file
268
scientific-skills/edgartools/references/companies.md
Normal file
@@ -0,0 +1,268 @@
|
||||
# edgartools — Companies Reference
|
||||
|
||||
## Table of Contents
|
||||
- [Finding Companies](#finding-companies)
|
||||
- [Company Properties](#company-properties)
|
||||
- [Filing Access](#filing-access)
|
||||
- [Financial Data Methods](#financial-data-methods)
|
||||
- [Company Screening](#company-screening)
|
||||
- [Advanced Search](#advanced-search)
|
||||
- [Company API Reference](#company-api-reference)
|
||||
- [Error Handling](#error-handling)
|
||||
|
||||
---
|
||||
|
||||
## Finding Companies
|
||||
|
||||
### By Ticker (case-insensitive)
|
||||
```python
|
||||
from edgar import Company
|
||||
company = Company("AAPL")
|
||||
company = Company("aapl") # same result
|
||||
```
|
||||
|
||||
### By CIK (fastest, most reliable)
|
||||
```python
|
||||
company = Company(320193)
|
||||
company = Company("320193")
|
||||
company = Company("0000320193") # zero-padded
|
||||
```
|
||||
|
||||
### By Name Search
|
||||
```python
|
||||
from edgar import find
|
||||
results = find("Apple")
|
||||
# Returns list: use results[0] or iterate
|
||||
for c in results:
|
||||
print(f"{c.ticker}: {c.name}")
|
||||
apple = results[0]
|
||||
```
|
||||
|
||||
### Multiple Share Classes
|
||||
```python
|
||||
brk_a = Company("BRK-A") # Class A
|
||||
brk_b = Company("BRK-B") # Class B
|
||||
# Both share the same CIK
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Company Properties
|
||||
|
||||
```python
|
||||
company = Company("MSFT")
|
||||
company.name # "Microsoft Corporation"
|
||||
company.cik # 789019
|
||||
company.display_name # "MSFT - Microsoft Corporation"
|
||||
company.ticker # "MSFT"
|
||||
company.tickers # ["MSFT"] (list of all tickers)
|
||||
company.industry # "SERVICES-PREPACKAGED SOFTWARE"
|
||||
company.sic # "7372"
|
||||
company.fiscal_year_end # "0630" (June 30)
|
||||
company.exchange # "Nasdaq"
|
||||
company.website # "https://www.microsoft.com"
|
||||
company.city # "Redmond"
|
||||
company.state # "WA"
|
||||
company.shares_outstanding # float (from SEC company facts)
|
||||
company.public_float # float in dollars
|
||||
company.is_company # True
|
||||
company.not_found # False if found
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Filing Access
|
||||
|
||||
### get_filings()
|
||||
```python
|
||||
# All filings
|
||||
filings = company.get_filings()
|
||||
|
||||
# Filter by form type
|
||||
annual = company.get_filings(form="10-K")
|
||||
multi = company.get_filings(form=["10-K", "10-Q"])
|
||||
|
||||
# Filter by date
|
||||
recent = company.get_filings(filing_date="2023-01-01:")
|
||||
range_ = company.get_filings(filing_date="2023-01-01:2023-12-31")
|
||||
|
||||
# Filter by year/quarter
|
||||
q4 = company.get_filings(year=2023, quarter=4)
|
||||
multi_year = company.get_filings(year=[2022, 2023])
|
||||
|
||||
# Other filters
|
||||
xbrl_only = company.get_filings(is_xbrl=True)
|
||||
original = company.get_filings(amendments=False)
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
- `form` — str or list of str
|
||||
- `year` — int, list, or range
|
||||
- `quarter` — 1, 2, 3, or 4
|
||||
- `filing_date` / `date` — "YYYY-MM-DD" or "YYYY-MM-DD:YYYY-MM-DD"
|
||||
- `amendments` — bool (default True)
|
||||
- `is_xbrl` — bool
|
||||
- `is_inline_xbrl` — bool
|
||||
- `sort_by` — field name (default "filing_date")
|
||||
|
||||
**Returns:** `EntityFilings` collection
|
||||
|
||||
### latest()
|
||||
```python
|
||||
latest_10k = company.latest("10-K") # single Filing
|
||||
latest_3 = company.latest("10-Q", 3) # list of Filings
|
||||
```
|
||||
|
||||
### Convenience Properties
|
||||
```python
|
||||
tenk = company.latest_tenk # TenK object or None
|
||||
tenq = company.latest_tenq # TenQ object or None
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Financial Data Methods
|
||||
|
||||
```python
|
||||
# Annual (from latest 10-K)
|
||||
financials = company.get_financials()
|
||||
|
||||
# Quarterly (from latest 10-Q)
|
||||
quarterly = company.get_quarterly_financials()
|
||||
|
||||
# XBRL facts
|
||||
facts = company.get_facts() # Returns EntityFacts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Company Screening
|
||||
|
||||
```python
|
||||
import pandas as pd
|
||||
from edgar import Company
|
||||
|
||||
tickers = ["AAPL", "MSFT", "NVDA", "AMZN", "META"]
|
||||
rows = []
|
||||
for ticker in tickers:
|
||||
company = Company(ticker)
|
||||
rows.append({
|
||||
'ticker': ticker,
|
||||
'name': company.name,
|
||||
'industry': company.industry,
|
||||
'shares_outstanding': company.shares_outstanding,
|
||||
'public_float': company.public_float,
|
||||
})
|
||||
|
||||
df = pd.DataFrame(rows)
|
||||
df = df.sort_values('public_float', ascending=False)
|
||||
|
||||
# Filter mega-caps (float > $1T)
|
||||
mega_caps = df[df['public_float'] > 1e12]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Advanced Search
|
||||
|
||||
### By Industry (SIC code)
|
||||
```python
|
||||
from edgar.reference import get_companies_by_industry
|
||||
software = get_companies_by_industry(sic=7372)
|
||||
```
|
||||
|
||||
### By Exchange
|
||||
```python
|
||||
from edgar.reference import get_companies_by_exchanges
|
||||
nyse = get_companies_by_exchanges("NYSE")
|
||||
nasdaq = get_companies_by_exchanges("Nasdaq")
|
||||
```
|
||||
|
||||
### By State
|
||||
```python
|
||||
from edgar.reference import get_companies_by_state
|
||||
delaware = get_companies_by_state("DE")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Company API Reference
|
||||
|
||||
### Constructor
|
||||
```python
|
||||
Company(cik_or_ticker: Union[str, int])
|
||||
```
|
||||
Raises `CompanyNotFoundError` if not found.
|
||||
|
||||
### Address Methods
|
||||
```python
|
||||
addr = company.business_address()
|
||||
# addr.street1, addr.city, addr.state_or_country, addr.zipcode
|
||||
|
||||
addr = company.mailing_address()
|
||||
```
|
||||
|
||||
### Utility Methods
|
||||
```python
|
||||
ticker = company.get_ticker() # primary ticker
|
||||
exchanges = company.get_exchanges() # list of exchange names
|
||||
company_data = company.data # EntityData with former_names, entity_type, flags
|
||||
```
|
||||
|
||||
### Factory Functions
|
||||
```python
|
||||
from edgar import get_company, get_entity
|
||||
company = get_company("AAPL") # same as Company("AAPL")
|
||||
entity = get_entity("AAPL")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
```python
|
||||
from edgar import Company
|
||||
|
||||
try:
|
||||
company = Company("INVALID")
|
||||
except Exception as e:
|
||||
# fallback to search
|
||||
results = find("Invalid Corp")
|
||||
if results:
|
||||
company = results[0]
|
||||
|
||||
# Check if found
|
||||
company = Company("MAYBE_INVALID")
|
||||
if company.not_found:
|
||||
print("Not available")
|
||||
else:
|
||||
filings = company.get_filings()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Batch Processing
|
||||
|
||||
```python
|
||||
tickers = ["AAPL", "MSFT", "GOOGL"]
|
||||
companies = []
|
||||
|
||||
for ticker in tickers:
|
||||
try:
|
||||
company = Company(ticker)
|
||||
companies.append({
|
||||
'ticker': ticker,
|
||||
'name': company.name,
|
||||
'cik': company.cik,
|
||||
'industry': company.industry,
|
||||
})
|
||||
except Exception as e:
|
||||
print(f"Error with {ticker}: {e}")
|
||||
```
|
||||
|
||||
## Performance Tips
|
||||
|
||||
1. Use CIK when possible — faster than ticker lookup
|
||||
2. Cache Company objects; avoid repeated API calls
|
||||
3. Filter filings with specific parameters in `get_filings()`
|
||||
4. Use reasonable date ranges to limit result sets
|
||||
237
scientific-skills/edgartools/references/data-objects.md
Normal file
237
scientific-skills/edgartools/references/data-objects.md
Normal file
@@ -0,0 +1,237 @@
|
||||
# edgartools — Data Objects Reference
|
||||
|
||||
Every SEC filing can be parsed into a structured Python object:
|
||||
|
||||
```python
|
||||
obj = filing.obj() # returns TenK, EightK, ThirteenF, Form4, etc.
|
||||
```
|
||||
|
||||
## Supported Forms
|
||||
|
||||
### Annual & Quarterly Reports (10-K / 10-Q) → TenK / TenQ
|
||||
|
||||
```python
|
||||
tenk = filing.obj() # or tenq for 10-Q
|
||||
|
||||
# Financial statements
|
||||
tenk.income_statement # formatted income statement
|
||||
tenk.balance_sheet # balance sheet
|
||||
tenk.financials # Financials object with all statements
|
||||
|
||||
# Document sections
|
||||
tenk.risk_factors # full risk factors text
|
||||
tenk.business # business description
|
||||
tenk.mda # management discussion & analysis
|
||||
|
||||
# Usage via Financials
|
||||
if tenk.financials:
|
||||
income = tenk.financials.income_statement
|
||||
balance = tenk.financials.balance_sheet
|
||||
cashflow = tenk.financials.cash_flow_statement
|
||||
```
|
||||
|
||||
**Note:** Always check `tenk.financials` before accessing — not all filings have XBRL data.
|
||||
|
||||
---
|
||||
|
||||
### Current Events (8-K) → EightK
|
||||
|
||||
```python
|
||||
eightk = filing.obj()
|
||||
|
||||
eightk.items # list of reported event codes (e.g. ["2.02", "9.01"])
|
||||
eightk.press_releases # attached press releases
|
||||
|
||||
print(f"Items: {eightk.items}")
|
||||
```
|
||||
|
||||
Common 8-K item codes:
|
||||
- `1.01` — Entry into material agreement
|
||||
- `2.02` — Results of operations (earnings)
|
||||
- `5.02` — Director/officer changes
|
||||
- `8.01` — Other events
|
||||
|
||||
---
|
||||
|
||||
### Insider Trades (Form 4) → Form4 (Ownership)
|
||||
|
||||
```python
|
||||
form4 = filing.obj()
|
||||
|
||||
form4.reporting_owner # insider name
|
||||
form4.transactions # buy/sell details with prices, shares, dates
|
||||
|
||||
# Get HTML table
|
||||
html = form4.to_html()
|
||||
```
|
||||
|
||||
Also covers:
|
||||
- Form 3 — Initial ownership statement
|
||||
- Form 5 — Annual changes in beneficial ownership
|
||||
|
||||
---
|
||||
|
||||
### Beneficial Ownership (SC 13D / SC 13G) → Schedule13D / Schedule13G
|
||||
|
||||
```python
|
||||
schedule = filing.obj()
|
||||
|
||||
schedule.total_shares # aggregate beneficial ownership
|
||||
schedule.items.item4_purpose_of_transaction # activist intent (13D only)
|
||||
schedule.items.item5_interest_in_securities # ownership percentage
|
||||
```
|
||||
|
||||
- **SC 13D**: Activist investors (5%+ with intent to influence)
|
||||
- **SC 13G**: Passive holders (5%+)
|
||||
|
||||
---
|
||||
|
||||
### Institutional Portfolios (13F-HR) → ThirteenF
|
||||
|
||||
```python
|
||||
thirteenf = filing.obj()
|
||||
|
||||
thirteenf.infotable # full holdings DataFrame
|
||||
thirteenf.total_value # portfolio market value
|
||||
|
||||
# Analyze holdings
|
||||
holdings_df = thirteenf.infotable
|
||||
print(holdings_df.head())
|
||||
print(f"Total AUM: ${thirteenf.total_value/1e9:.1f}B")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Proxy & Governance (DEF 14A) → ProxyStatement
|
||||
|
||||
```python
|
||||
proxy = filing.obj()
|
||||
|
||||
proxy.executive_compensation # pay tables (5-year DataFrame)
|
||||
proxy.proposals # shareholder vote items
|
||||
proxy.peo_name # "Mr. Cook" (principal exec officer)
|
||||
proxy.peo_total_comp # CEO total compensation
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Private Offerings (Form D) → FormD
|
||||
|
||||
```python
|
||||
formd = filing.obj()
|
||||
|
||||
formd.offering # offering details and amounts
|
||||
formd.recipients # related persons
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Crowdfunding Offerings (Form C) → FormC
|
||||
|
||||
```python
|
||||
formc = filing.obj()
|
||||
|
||||
formc.offering_information # target amount, deadline, securities
|
||||
formc.annual_report_disclosure # issuer financials (C-AR)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Insider Sale Notices (Form 144) → Form144
|
||||
|
||||
```python
|
||||
form144 = filing.obj()
|
||||
|
||||
form144.proposed_sale_amount # shares to be sold
|
||||
form144.securities # security details
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Fund Voting Records (N-PX) → FundReport
|
||||
|
||||
```python
|
||||
npx = filing.obj()
|
||||
|
||||
npx.votes # vote records by proposal
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### ABS Distribution Reports (Form 10-D) → TenD (CMBS only)
|
||||
|
||||
```python
|
||||
ten_d = filing.obj()
|
||||
|
||||
ten_d.loans # loan-level DataFrame
|
||||
ten_d.properties # property-level DataFrame
|
||||
ten_d.asset_data.summary() # pool statistics
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Municipal Advisors (MA-I) → MunicipalAdvisorForm
|
||||
|
||||
```python
|
||||
mai = filing.obj()
|
||||
mai.advisor_name # advisor details
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Foreign Private Issuers (20-F) → TwentyF
|
||||
|
||||
```python
|
||||
twentyf = filing.obj()
|
||||
twentyf.financials # financial data for foreign issuers
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Complete Form → Class Mapping
|
||||
|
||||
| Form | Class | Key Attributes |
|
||||
|------|-------|----------------|
|
||||
| 10-K | TenK | `financials`, `income_statement`, `risk_factors`, `business` |
|
||||
| 10-Q | TenQ | `financials`, `income_statement`, `balance_sheet` |
|
||||
| 8-K | EightK | `items`, `press_releases` |
|
||||
| 20-F | TwentyF | `financials` |
|
||||
| 3 | Form3 | initial ownership |
|
||||
| 4 | Form4 | `reporting_owner`, `transactions` |
|
||||
| 5 | Form5 | annual ownership changes |
|
||||
| DEF 14A | ProxyStatement | `executive_compensation`, `proposals`, `peo_name` |
|
||||
| 13F-HR | ThirteenF | `infotable`, `total_value` |
|
||||
| SC 13D | Schedule13D | `total_shares`, `items` |
|
||||
| SC 13G | Schedule13G | `total_shares` |
|
||||
| NPORT-P | NportFiling | fund portfolio |
|
||||
| 144 | Form144 | `proposed_sale_amount`, `securities` |
|
||||
| N-PX | FundReport | `votes` |
|
||||
| Form D | FormD | `offering`, `recipients` |
|
||||
| Form C | FormC | `offering_information` |
|
||||
| 10-D | TenD | `loans`, `properties`, `asset_data` |
|
||||
| MA-I | MunicipalAdvisorForm | `advisor_name` |
|
||||
|
||||
---
|
||||
|
||||
## How It Works
|
||||
|
||||
```python
|
||||
from edgar import Company
|
||||
|
||||
apple = Company("AAPL")
|
||||
filing = apple.get_latest_filing("10-K")
|
||||
tenk = filing.obj() # returns TenK with all sections and financials
|
||||
```
|
||||
|
||||
If a form type is not yet supported, `filing.obj()` raises `UnsupportedFilingTypeError`.
|
||||
|
||||
## Pattern for Unknown Form Types
|
||||
|
||||
```python
|
||||
obj = filing.obj()
|
||||
if obj is None:
|
||||
# Fallback to raw content
|
||||
text = filing.text()
|
||||
html = filing.html()
|
||||
xbrl = filing.xbrl()
|
||||
```
|
||||
372
scientific-skills/edgartools/references/entity-facts.md
Normal file
372
scientific-skills/edgartools/references/entity-facts.md
Normal file
@@ -0,0 +1,372 @@
|
||||
# edgartools — EntityFacts Reference
|
||||
|
||||
Structured access to SEC company financial facts with AI-ready features, querying, and professional formatting.
|
||||
|
||||
## Table of Contents
|
||||
- [EntityFacts Class](#entityfacts-class)
|
||||
- [FactQuery — Fluent Query Builder](#factquery--fluent-query-builder)
|
||||
- [FinancialStatement Class](#financialstatement-class)
|
||||
- [FinancialFact Class](#financialfact-class)
|
||||
- [Common Patterns](#common-patterns)
|
||||
|
||||
---
|
||||
|
||||
## EntityFacts Class
|
||||
|
||||
### Getting EntityFacts
|
||||
|
||||
```python
|
||||
from edgar import Company
|
||||
|
||||
company = Company("AAPL")
|
||||
facts = company.get_facts() # Returns EntityFacts object
|
||||
```
|
||||
|
||||
### Core Properties
|
||||
|
||||
```python
|
||||
facts.cik # 320193
|
||||
facts.name # "Apple Inc."
|
||||
len(facts) # total number of facts
|
||||
|
||||
# DEI properties (from SEC filings)
|
||||
facts.shares_outstanding # float or None
|
||||
facts.public_float # float or None
|
||||
facts.shares_outstanding_fact # FinancialFact with full metadata
|
||||
facts.public_float_fact # FinancialFact with full metadata
|
||||
```
|
||||
|
||||
### Financial Statement Methods
|
||||
|
||||
```python
|
||||
# Income statement
|
||||
stmt = facts.income_statement() # FinancialStatement (4 annual periods)
|
||||
stmt = facts.income_statement(periods=8) # 8 periods
|
||||
stmt = facts.income_statement(annual=False) # quarterly
|
||||
df = facts.income_statement(as_dataframe=True) # return DataFrame directly
|
||||
|
||||
# Balance sheet
|
||||
stmt = facts.balance_sheet()
|
||||
stmt = facts.balance_sheet(periods=4)
|
||||
stmt = facts.balance_sheet(as_of=date(2024, 12, 31)) # point-in-time
|
||||
|
||||
# Cash flow
|
||||
stmt = facts.cash_flow()
|
||||
stmt = facts.cashflow_statement(periods=5, annual=True)
|
||||
|
||||
# Parameters:
|
||||
# periods (int): number of periods (default: 4)
|
||||
# annual (bool): True=annual, False=quarterly (default: True)
|
||||
# period_length (int): months — 3=quarterly, 12=annual
|
||||
# as_dataframe (bool): return DataFrame instead of FinancialStatement
|
||||
# as_of (date): balance sheet only — point-in-time snapshot
|
||||
```
|
||||
|
||||
### Query Interface
|
||||
|
||||
```python
|
||||
query = facts.query()
|
||||
# Returns FactQuery builder — see FactQuery section
|
||||
```
|
||||
|
||||
### Get Single Fact
|
||||
|
||||
```python
|
||||
revenue_fact = facts.get_fact('Revenue')
|
||||
q1_revenue = facts.get_fact('Revenue', '2024-Q1')
|
||||
# Returns FinancialFact or None
|
||||
```
|
||||
|
||||
### Time Series
|
||||
|
||||
```python
|
||||
revenue_ts = facts.time_series('Revenue', periods=8) # DataFrame
|
||||
```
|
||||
|
||||
### DEI / Entity Info
|
||||
|
||||
```python
|
||||
# DEI facts DataFrame
|
||||
dei_df = facts.dei_facts()
|
||||
dei_df = facts.dei_facts(as_of=date(2024, 12, 31))
|
||||
|
||||
# Entity info dict
|
||||
info = facts.entity_info()
|
||||
print(info['entity_name'])
|
||||
print(info['shares_outstanding'])
|
||||
```
|
||||
|
||||
### AI / LLM Methods
|
||||
|
||||
```python
|
||||
# Comprehensive LLM context
|
||||
context = facts.to_llm_context(
|
||||
focus_areas=['profitability', 'growth'], # or 'liquidity'
|
||||
time_period='5Y' # 'recent', '5Y', '10Y', 'all'
|
||||
)
|
||||
|
||||
# MCP-compatible tool definitions
|
||||
tools = facts.to_agent_tools()
|
||||
```
|
||||
|
||||
### Iteration
|
||||
|
||||
```python
|
||||
for fact in facts:
|
||||
print(f"{fact.concept}: {fact.numeric_value}")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## FactQuery — Fluent Query Builder
|
||||
|
||||
Create via `facts.query()`. All filter methods return `self` for chaining.
|
||||
|
||||
### Concept Filtering
|
||||
|
||||
```python
|
||||
query = facts.query()
|
||||
|
||||
# Fuzzy matching (default)
|
||||
q = query.by_concept('Revenue')
|
||||
|
||||
# Exact matching
|
||||
q = query.by_concept('us-gaap:Revenue', exact=True)
|
||||
|
||||
# By human-readable label
|
||||
q = query.by_label('Total Revenue', fuzzy=True)
|
||||
q = query.by_label('Revenue', fuzzy=False)
|
||||
```
|
||||
|
||||
### Time-Based Filtering
|
||||
|
||||
```python
|
||||
# Fiscal year
|
||||
q = query.by_fiscal_year(2024)
|
||||
|
||||
# Fiscal period
|
||||
q = query.by_fiscal_period('FY') # 'FY', 'Q1', 'Q2', 'Q3', 'Q4'
|
||||
q = query.by_fiscal_period('Q1')
|
||||
|
||||
# Period length in months
|
||||
q = query.by_period_length(3) # quarterly
|
||||
q = query.by_period_length(12) # annual
|
||||
|
||||
# Date range
|
||||
q = query.date_range(start=date(2023, 1, 1), end=date(2024, 12, 31))
|
||||
|
||||
# Point-in-time
|
||||
q = query.as_of(date(2024, 6, 30))
|
||||
|
||||
# Latest n periods
|
||||
q = query.latest_periods(4, annual=True)
|
||||
q = query.latest_instant() # most recent balance sheet items
|
||||
```
|
||||
|
||||
### Statement / Form Filtering
|
||||
|
||||
```python
|
||||
q = query.by_statement_type('IncomeStatement')
|
||||
q = query.by_statement_type('BalanceSheet')
|
||||
q = query.by_statement_type('CashFlow')
|
||||
|
||||
q = query.by_form_type('10-K')
|
||||
q = query.by_form_type(['10-K', '10-Q'])
|
||||
```
|
||||
|
||||
### Quality Filtering
|
||||
|
||||
```python
|
||||
q = query.high_quality_only() # audited facts only
|
||||
q = query.min_confidence(0.9) # confidence score 0.0-1.0
|
||||
```
|
||||
|
||||
### Sorting
|
||||
|
||||
```python
|
||||
q = query.sort_by('filing_date', ascending=False)
|
||||
q = query.sort_by('fiscal_year')
|
||||
```
|
||||
|
||||
### Execution
|
||||
|
||||
```python
|
||||
# Execute and return facts
|
||||
facts_list = query.execute() # List[FinancialFact]
|
||||
count = query.count() # int (no fetch)
|
||||
latest_n = query.latest(5) # List[FinancialFact] (most recent)
|
||||
|
||||
# Convert to DataFrame
|
||||
df = query.to_dataframe()
|
||||
df = query.to_dataframe('label', 'numeric_value', 'fiscal_period')
|
||||
|
||||
# Pivot by period
|
||||
stmt = query.pivot_by_period() # FinancialStatement
|
||||
df = query.pivot_by_period(return_statement=False) # DataFrame
|
||||
|
||||
# LLM context
|
||||
llm_data = query.to_llm_context()
|
||||
```
|
||||
|
||||
### Full Chaining Example
|
||||
|
||||
```python
|
||||
results = facts.query()\
|
||||
.by_concept('Revenue')\
|
||||
.by_fiscal_year(2024)\
|
||||
.by_form_type('10-K')\
|
||||
.sort_by('filing_date')\
|
||||
.execute()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## FinancialStatement Class
|
||||
|
||||
Wrapper around DataFrame with intelligent formatting and display.
|
||||
|
||||
### Properties
|
||||
|
||||
```python
|
||||
stmt = company.income_statement()
|
||||
|
||||
stmt.shape # (10, 4) — rows x periods
|
||||
stmt.columns # period labels: ['FY 2024', 'FY 2023', ...]
|
||||
stmt.index # concept names: ['Revenue', 'Cost of Revenue', ...]
|
||||
stmt.empty # bool
|
||||
```
|
||||
|
||||
### Methods
|
||||
|
||||
```python
|
||||
# Get numeric DataFrame for calculations
|
||||
numeric_df = stmt.to_numeric()
|
||||
growth_rates = numeric_df.pct_change(axis=1)
|
||||
|
||||
# Get specific concept across periods
|
||||
revenue_series = stmt.get_concept('Revenue') # pd.Series or None
|
||||
|
||||
# Calculate period-over-period growth
|
||||
growth = stmt.calculate_growth('Revenue', periods=1) # pd.Series
|
||||
|
||||
# Format a value
|
||||
formatted = stmt.format_value(1234567, 'Revenue') # "$1,234,567"
|
||||
|
||||
# LLM context
|
||||
context = stmt.to_llm_context()
|
||||
```
|
||||
|
||||
### Display
|
||||
|
||||
- Jupyter: automatic HTML rendering with professional styling
|
||||
- Console: formatted text with proper alignment
|
||||
- Compatible with Rich library
|
||||
|
||||
---
|
||||
|
||||
## FinancialFact Class
|
||||
|
||||
Individual fact with full metadata.
|
||||
|
||||
### Core Attributes
|
||||
|
||||
```python
|
||||
fact = facts.get_fact('Revenue')
|
||||
|
||||
fact.concept # "us-gaap:Revenue"
|
||||
fact.taxonomy # "us-gaap"
|
||||
fact.label # "Revenue"
|
||||
fact.value # raw value
|
||||
fact.numeric_value # float for calculations
|
||||
fact.unit # "USD", "shares", etc.
|
||||
fact.scale # 1000, 1000000, etc.
|
||||
```
|
||||
|
||||
### Temporal Attributes
|
||||
|
||||
```python
|
||||
fact.period_start # date (for duration facts)
|
||||
fact.period_end # date
|
||||
fact.period_type # "instant" or "duration"
|
||||
fact.fiscal_year # int
|
||||
fact.fiscal_period # "FY", "Q1", "Q2", "Q3", "Q4"
|
||||
```
|
||||
|
||||
### Filing Context
|
||||
|
||||
```python
|
||||
fact.filing_date # date filed
|
||||
fact.form_type # "10-K", "10-Q", etc.
|
||||
fact.accession # SEC accession number
|
||||
```
|
||||
|
||||
### Quality
|
||||
|
||||
```python
|
||||
fact.data_quality # DataQuality.HIGH / MEDIUM / LOW
|
||||
fact.is_audited # bool
|
||||
fact.confidence_score # float 0.0-1.0
|
||||
```
|
||||
|
||||
### AI Attributes
|
||||
|
||||
```python
|
||||
fact.semantic_tags # List[str]
|
||||
fact.business_context # str description
|
||||
```
|
||||
|
||||
### Methods
|
||||
|
||||
```python
|
||||
context = fact.to_llm_context() # dict for LLM
|
||||
formatted = fact.get_formatted_value() # "365,817,000,000"
|
||||
period_key = fact.get_display_period_key() # "Q1 2024", "FY 2023"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Multi-Period Income Analysis
|
||||
|
||||
```python
|
||||
from edgar import Company
|
||||
|
||||
company = Company("AAPL")
|
||||
facts = company.get_facts()
|
||||
|
||||
# 4 annual periods
|
||||
stmt = facts.income_statement(periods=4, annual=True)
|
||||
print(stmt)
|
||||
|
||||
# Convert to numeric for calculations
|
||||
numeric = stmt.to_numeric()
|
||||
revenue_growth = numeric.loc['Revenue'].pct_change()
|
||||
print(revenue_growth)
|
||||
```
|
||||
|
||||
### Query Latest Revenue Facts
|
||||
|
||||
```python
|
||||
latest_revenue = facts.query()\
|
||||
.by_concept('Revenue')\
|
||||
.latest_periods(4, annual=True)\
|
||||
.to_dataframe()
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
|
||||
```python
|
||||
from edgar.entity.core import NoCompanyFactsFound
|
||||
|
||||
try:
|
||||
facts = company.get_facts()
|
||||
except NoCompanyFactsFound:
|
||||
print("No facts available")
|
||||
|
||||
# Methods return None gracefully
|
||||
stmt = facts.income_statement() # None if no data
|
||||
if stmt and not stmt.empty:
|
||||
# process
|
||||
pass
|
||||
```
|
||||
387
scientific-skills/edgartools/references/filings.md
Normal file
387
scientific-skills/edgartools/references/filings.md
Normal file
@@ -0,0 +1,387 @@
|
||||
# edgartools — Filings Reference
|
||||
|
||||
## Table of Contents
|
||||
- [Getting a Filing](#getting-a-filing)
|
||||
- [Filing Properties](#filing-properties)
|
||||
- [Accessing Content](#accessing-content)
|
||||
- [Structured Data](#structured-data)
|
||||
- [Attachments & Exhibits](#attachments--exhibits)
|
||||
- [Search Within a Filing](#search-within-a-filing)
|
||||
- [Viewing & Display](#viewing--display)
|
||||
- [Save, Load & Export](#save-load--export)
|
||||
- [Filings Collection API](#filings-collection-api)
|
||||
- [Filtering & Navigation](#filtering--navigation)
|
||||
|
||||
---
|
||||
|
||||
## Getting a Filing
|
||||
|
||||
```python
|
||||
from edgar import Company, get_filings, get_by_accession_number, Filing
|
||||
|
||||
# From a company
|
||||
company = Company("AAPL")
|
||||
filing = company.get_filings(form="10-K").latest()
|
||||
|
||||
# Global search
|
||||
filings = get_filings(2024, 1, form="10-K")
|
||||
filing = filings[0]
|
||||
filing = filings.latest()
|
||||
|
||||
# By accession number
|
||||
filing = get_by_accession_number("0000320193-23-000106")
|
||||
|
||||
# Direct construction (rarely needed)
|
||||
filing = Filing(
|
||||
form='10-Q',
|
||||
filing_date='2024-06-30',
|
||||
company='Tesla Inc.',
|
||||
cik=1318605,
|
||||
accession_no='0001628280-24-028839'
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Filing Properties
|
||||
|
||||
### Basic Properties
|
||||
```python
|
||||
filing.cik # 320193
|
||||
filing.company # "Apple Inc."
|
||||
filing.form # "10-K"
|
||||
filing.filing_date # "2023-11-03"
|
||||
filing.period_of_report # "2023-09-30"
|
||||
filing.accession_no # "0000320193-23-000106"
|
||||
filing.accession_number # alias for accession_no
|
||||
```
|
||||
|
||||
### EntityFiling Extra Properties (from company.get_filings())
|
||||
```python
|
||||
filing.acceptance_datetime # datetime
|
||||
filing.file_number # "001-36743"
|
||||
filing.size # bytes
|
||||
filing.primary_document # filename
|
||||
filing.is_xbrl # bool
|
||||
filing.is_inline_xbrl # bool
|
||||
```
|
||||
|
||||
### URL Properties
|
||||
```python
|
||||
filing.homepage_url # SEC index page URL
|
||||
filing.filing_url # primary document URL
|
||||
filing.text_url # text version URL
|
||||
filing.base_dir # base directory for all files
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Accessing Content
|
||||
|
||||
```python
|
||||
html = filing.html() # HTML string or None
|
||||
text = filing.text() # plain text (clean)
|
||||
md = filing.markdown() # markdown string
|
||||
xml = filing.xml() # XML string or None (ownership forms)
|
||||
full = filing.full_text_submission() # complete SGML submission
|
||||
|
||||
# Markdown with page breaks (good for LLM processing)
|
||||
md = filing.markdown(include_page_breaks=True, start_page_number=1)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Structured Data
|
||||
|
||||
### Get Form-Specific Object (Primary Method)
|
||||
```python
|
||||
obj = filing.obj() # or filing.data_object()
|
||||
# Returns: TenK, TenQ, EightK, Form4, ThirteenF, ProxyStatement, etc.
|
||||
```
|
||||
|
||||
**IMPORTANT:** The base `Filing` class has NO `financials` property.
|
||||
|
||||
```python
|
||||
# WRONG:
|
||||
filing.financials # AttributeError!
|
||||
|
||||
# CORRECT:
|
||||
tenk = filing.obj()
|
||||
if tenk and tenk.financials:
|
||||
income = tenk.financials.income_statement
|
||||
```
|
||||
|
||||
### Form → Class Mapping
|
||||
| Form | Class | Module |
|
||||
|------|-------|--------|
|
||||
| 10-K | TenK | edgar.company_reports |
|
||||
| 10-Q | TenQ | edgar.company_reports |
|
||||
| 8-K | EightK | edgar.company_reports |
|
||||
| 20-F | TwentyF | edgar.company_reports |
|
||||
| 4 | Form4 | edgar.ownership |
|
||||
| 3 | Form3 | edgar.ownership |
|
||||
| 5 | Form5 | edgar.ownership |
|
||||
| DEF 14A | ProxyStatement | edgar.proxy |
|
||||
| 13F-HR | ThirteenF | edgar.holdings |
|
||||
| SC 13D/G | Schedule13 | edgar.ownership |
|
||||
| NPORT-P | NportFiling | edgar.nport |
|
||||
| 144 | Form144 | edgar.ownership |
|
||||
|
||||
### Get XBRL Data
|
||||
```python
|
||||
xbrl = filing.xbrl() # Returns XBRL object or None
|
||||
if xbrl:
|
||||
income = xbrl.statements.income_statement()
|
||||
balance = xbrl.statements.balance_sheet()
|
||||
cashflow = xbrl.statements.cash_flow_statement()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Attachments & Exhibits
|
||||
|
||||
### List Attachments
|
||||
```python
|
||||
attachments = filing.attachments
|
||||
print(f"Total: {len(attachments)}")
|
||||
|
||||
for att in attachments:
|
||||
print(f"{att.sequence}: {att.description}")
|
||||
print(f" Type: {att.document_type}")
|
||||
print(f" File: {att.document}")
|
||||
```
|
||||
|
||||
### Primary Document
|
||||
```python
|
||||
primary = filing.document
|
||||
```
|
||||
|
||||
### Access by Index or Name
|
||||
```python
|
||||
first = filing.attachments[0]
|
||||
specific = filing.attachments["ex-10_1.htm"]
|
||||
```
|
||||
|
||||
### Download Attachments
|
||||
```python
|
||||
filing.attachments[0].download("./downloads/")
|
||||
filing.attachments.download("./downloads/") # all
|
||||
```
|
||||
|
||||
### Work with Exhibits
|
||||
```python
|
||||
exhibits = filing.exhibits
|
||||
|
||||
for exhibit in exhibits:
|
||||
print(f"Exhibit {exhibit.exhibit_number}: {exhibit.description}")
|
||||
if exhibit.exhibit_number == "10.1":
|
||||
exhibit.download("./exhibits/")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Search Within a Filing
|
||||
|
||||
```python
|
||||
# Simple text search
|
||||
results = filing.search("artificial intelligence")
|
||||
print(f"Found {len(results)} mentions")
|
||||
|
||||
# Regex search
|
||||
emails = filing.search(
|
||||
r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b',
|
||||
regex=True
|
||||
)
|
||||
|
||||
# Financial terms
|
||||
revenue_mentions = filing.search("revenue")
|
||||
risk_factors = filing.search("risk factor")
|
||||
critical = filing.search(r'\b(material weakness|restatement)\b', regex=True)
|
||||
```
|
||||
|
||||
### Document Sections
|
||||
```python
|
||||
sections = filing.sections() # list of section names
|
||||
doc = filing.parse() # parse to Document for advanced ops
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Viewing & Display
|
||||
|
||||
```python
|
||||
filing.view() # display in console/Jupyter with Rich
|
||||
filing.open() # open primary doc in browser
|
||||
filing.open_homepage() # open SEC index page
|
||||
filing.serve(port=8080) # serve locally at http://localhost:8080
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Save, Load & Export
|
||||
|
||||
```python
|
||||
# Save
|
||||
filing.save("./data/filings/") # auto-generates filename
|
||||
filing.save("./data/apple_10k.pkl") # specific file
|
||||
|
||||
# Load
|
||||
filing = Filing.load("./data/apple_10k.pkl")
|
||||
|
||||
# Export
|
||||
data = filing.to_dict()
|
||||
summary_df = filing.summary()
|
||||
|
||||
# Download raw
|
||||
filing.download(data_directory="./raw_filings/", compress=False)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Filings Collection API
|
||||
|
||||
### get_filings() — Global Search
|
||||
```python
|
||||
from edgar import get_filings
|
||||
|
||||
filings = get_filings(2024, 1, form="10-K") # Q1 2024 10-Ks
|
||||
filings = get_filings(2023, form="10-K") # all 2023 10-Ks
|
||||
filings = get_filings([2022, 2023, 2024]) # multiple years
|
||||
filings = get_filings(2024, [1, 2], form="10-Q")
|
||||
filings = get_filings(2024, 1, amendments=False)
|
||||
```
|
||||
|
||||
**Note:** `get_filings()` has NO `limit` parameter. Use `.head(n)` after.
|
||||
|
||||
### Collection Properties
|
||||
```python
|
||||
len(filings) # count
|
||||
filings.empty # bool
|
||||
filings.date_range # (start_date, end_date)
|
||||
filings.start_date # earliest
|
||||
filings.end_date # latest
|
||||
```
|
||||
|
||||
### Access & Iteration
|
||||
```python
|
||||
first = filings[0]
|
||||
last = filings[-1]
|
||||
|
||||
for filing in filings:
|
||||
print(f"{filing.form}: {filing.company}")
|
||||
|
||||
# By accession number
|
||||
filing = filings.get("0001234567-24-000001")
|
||||
```
|
||||
|
||||
### Subset Operations
|
||||
```python
|
||||
filings.latest() # most recent (single Filing)
|
||||
filings.latest(10) # 10 most recent (Filings)
|
||||
filings.head(20) # first 20
|
||||
filings.tail(20) # last 20
|
||||
filings.sample(10) # random 10
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Filtering & Navigation
|
||||
|
||||
### filter()
|
||||
```python
|
||||
# Form type
|
||||
annual = filings.filter(form="10-K")
|
||||
multi = filings.filter(form=["10-K", "10-Q"])
|
||||
original = filings.filter(form="10-K", amendments=False)
|
||||
|
||||
# Date
|
||||
jan = filings.filter(date="2024-01-01")
|
||||
q1 = filings.filter(date="2024-01-01:2024-03-31")
|
||||
recent = filings.filter(date="2024-01-01:")
|
||||
|
||||
# Company
|
||||
apple = filings.filter(ticker="AAPL")
|
||||
apple = filings.filter(cik=320193)
|
||||
faang = filings.filter(ticker=["AAPL", "MSFT", "GOOGL"])
|
||||
|
||||
# Exchange
|
||||
nasdaq = filings.filter(exchange="NASDAQ")
|
||||
major = filings.filter(exchange=["NASDAQ", "NYSE"])
|
||||
```
|
||||
|
||||
### Chain Filters
|
||||
```python
|
||||
result = (filings
|
||||
.filter(form="10-K")
|
||||
.filter(exchange="NASDAQ")
|
||||
.filter(date="2024-01-01:")
|
||||
.latest(50))
|
||||
```
|
||||
|
||||
### Find by Company Name
|
||||
```python
|
||||
tech = filings.find("Technology")
|
||||
apple = filings.find("Apple")
|
||||
```
|
||||
|
||||
### Pagination
|
||||
```python
|
||||
next_page = filings.next()
|
||||
prev_page = filings.previous()
|
||||
current = filings.current()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Export & Persistence
|
||||
|
||||
```python
|
||||
df = filings.to_pandas()
|
||||
df = filings.to_pandas('form', 'company', 'filing_date', 'cik')
|
||||
|
||||
filings.save_parquet("filings.parquet") # or .save()
|
||||
filings.download(data_directory="./raw_data/", compress=True)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Recipes
|
||||
|
||||
### Extract Revenue from Latest 10-K
|
||||
```python
|
||||
company = Company("MSFT")
|
||||
filing = company.get_filings(form="10-K").latest()
|
||||
tenk = filing.obj()
|
||||
if tenk.financials:
|
||||
income = tenk.financials.income_statement
|
||||
print(income)
|
||||
```
|
||||
|
||||
### Convert to Markdown for LLM Analysis
|
||||
```python
|
||||
company = Company("NVDA")
|
||||
filing = company.get_filings(form="10-K").latest()
|
||||
md = filing.markdown(include_page_breaks=True)
|
||||
with open("nvidia_10k.md", "w") as f:
|
||||
f.write(md)
|
||||
```
|
||||
|
||||
### Search Across Recent 8-K Filings
|
||||
```python
|
||||
filings = get_filings(2024, 1, form="8-K").head(50)
|
||||
for filing in filings:
|
||||
if filing.search("earnings"):
|
||||
print(f"{filing.company} ({filing.filing_date})")
|
||||
```
|
||||
|
||||
### Batch Process with Pagination
|
||||
```python
|
||||
def process_all(filings):
|
||||
current = filings
|
||||
results = []
|
||||
while current and not current.empty:
|
||||
for filing in current:
|
||||
results.append(filing.to_dict())
|
||||
current = current.next()
|
||||
return results
|
||||
```
|
||||
274
scientific-skills/edgartools/references/financial-data.md
Normal file
274
scientific-skills/edgartools/references/financial-data.md
Normal file
@@ -0,0 +1,274 @@
|
||||
# edgartools — Financial Data Reference
|
||||
|
||||
## Table of Contents
|
||||
- [Quick Start](#quick-start)
|
||||
- [Available Statements](#available-statements)
|
||||
- [Convenience Methods](#convenience-methods)
|
||||
- [Detail Levels (Views)](#detail-levels-views)
|
||||
- [DataFrame Export](#dataframe-export)
|
||||
- [Quarterly vs Annual](#quarterly-vs-annual)
|
||||
- [Multi-Period Analysis](#multi-period-analysis)
|
||||
- [Raw XBRL Facts Query](#raw-xbrl-facts-query)
|
||||
- [API Quick Reference](#api-quick-reference)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
```python
|
||||
from edgar import Company
|
||||
|
||||
company = Company("AAPL")
|
||||
|
||||
# Annual (from latest 10-K)
|
||||
financials = company.get_financials()
|
||||
income = financials.income_statement()
|
||||
|
||||
# Quarterly (from latest 10-Q)
|
||||
quarterly = company.get_quarterly_financials()
|
||||
income = quarterly.income_statement()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Available Statements
|
||||
|
||||
```python
|
||||
financials = company.get_financials()
|
||||
|
||||
income = financials.income_statement()
|
||||
balance = financials.balance_sheet()
|
||||
cashflow = financials.cashflow_statement() # note: no underscore
|
||||
equity = financials.statement_of_equity()
|
||||
comprehensive = financials.comprehensive_income()
|
||||
```
|
||||
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `income_statement()` | Revenue, COGS, operating income, net income |
|
||||
| `balance_sheet()` | Assets, liabilities, equity |
|
||||
| `cashflow_statement()` | Operating, investing, financing cash flows |
|
||||
| `statement_of_equity()` | Changes in stockholders' equity |
|
||||
| `comprehensive_income()` | Net income + other comprehensive income |
|
||||
|
||||
---
|
||||
|
||||
## Convenience Methods
|
||||
|
||||
Get single values directly:
|
||||
|
||||
```python
|
||||
financials = company.get_financials()
|
||||
|
||||
revenue = financials.get_revenue()
|
||||
net_income = financials.get_net_income()
|
||||
total_assets = financials.get_total_assets()
|
||||
total_liabs = financials.get_total_liabilities()
|
||||
equity = financials.get_stockholders_equity()
|
||||
op_cash_flow = financials.get_operating_cash_flow()
|
||||
free_cash_flow = financials.get_free_cash_flow()
|
||||
capex = financials.get_capital_expenditures()
|
||||
current_assets = financials.get_current_assets()
|
||||
current_liabs = financials.get_current_liabilities()
|
||||
|
||||
# All key metrics at once
|
||||
metrics = financials.get_financial_metrics() # dict
|
||||
|
||||
# Prior period: period_offset=1 (previous), 0=current
|
||||
prev_revenue = financials.get_revenue(period_offset=1)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Detail Levels (Views)
|
||||
|
||||
Control the level of detail in financial statements:
|
||||
|
||||
```python
|
||||
income = financials.income_statement()
|
||||
|
||||
# Summary: ~15-20 rows, matches SEC Viewer
|
||||
df_summary = income.to_dataframe(view="summary")
|
||||
|
||||
# Standard (default): ~25-35 rows, matches filing document
|
||||
df_standard = income.to_dataframe(view="standard")
|
||||
|
||||
# Detailed: ~50+ rows, all dimensional breakdowns
|
||||
df_detailed = income.to_dataframe(view="detailed")
|
||||
```
|
||||
|
||||
| View | Use Case |
|
||||
|------|----------|
|
||||
| `"summary"` | Quick overview, validating against SEC Viewer |
|
||||
| `"standard"` | Display, full context (default) |
|
||||
| `"detailed"` | Data extraction, segment analysis |
|
||||
|
||||
**Example — Apple Revenue breakdown:**
|
||||
- Summary: `Revenue $391,035M`
|
||||
- Standard: `Products $298,085M`, `Services $92,950M`
|
||||
- Detailed: iPhone, Mac, iPad, Wearables separately
|
||||
|
||||
---
|
||||
|
||||
## DataFrame Export
|
||||
|
||||
```python
|
||||
income = financials.income_statement()
|
||||
|
||||
# Convert to DataFrame
|
||||
df = income.to_dataframe()
|
||||
df = income.to_dataframe(view="detailed")
|
||||
|
||||
# Export
|
||||
df.to_csv("apple_income.csv")
|
||||
df.to_excel("apple_income.xlsx")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quarterly vs Annual
|
||||
|
||||
| Need | Method |
|
||||
|------|--------|
|
||||
| Annual (10-K) | `company.get_financials()` |
|
||||
| Quarterly (10-Q) | `company.get_quarterly_financials()` |
|
||||
|
||||
```python
|
||||
quarterly = company.get_quarterly_financials()
|
||||
q_income = quarterly.income_statement()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Multi-Period Analysis
|
||||
|
||||
Use `XBRLS` to analyze trends across multiple filings:
|
||||
|
||||
```python
|
||||
from edgar.xbrl import XBRLS
|
||||
|
||||
# Get last 3 annual filings (use amendments=False)
|
||||
filings = company.get_filings(form="10-K", amendments=False).head(3)
|
||||
|
||||
# Stitch together
|
||||
xbrls = XBRLS.from_filings(filings)
|
||||
|
||||
# Get aligned multi-period statements
|
||||
income = xbrls.statements.income_statement()
|
||||
income_detailed = xbrls.statements.income_statement(view="detailed")
|
||||
|
||||
balance = xbrls.statements.balance_sheet()
|
||||
cashflow = xbrls.statements.cashflow_statement()
|
||||
|
||||
# Convert to DataFrame (periods as columns)
|
||||
df = income.to_dataframe()
|
||||
print(df)
|
||||
```
|
||||
|
||||
**Why `amendments=False`?** Amended filings (10-K/A) sometimes contain only corrected sections, not complete financial statements, which breaks multi-period stitching.
|
||||
|
||||
---
|
||||
|
||||
## Raw XBRL Facts Query
|
||||
|
||||
For research or custom calculations:
|
||||
|
||||
```python
|
||||
xbrl = filing.xbrl()
|
||||
|
||||
# Find revenue facts
|
||||
revenue_facts = xbrl.facts.query()\
|
||||
.by_concept("Revenue")\
|
||||
.to_dataframe()
|
||||
|
||||
# Search by label
|
||||
rd_facts = xbrl.facts.query()\
|
||||
.by_label("Research", exact=False)\
|
||||
.to_dataframe()
|
||||
|
||||
# Filter by value range
|
||||
large_items = xbrl.facts.query()\
|
||||
.by_value(min_value=1_000_000_000)\
|
||||
.to_dataframe()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Quick Reference
|
||||
|
||||
### Company-Level
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `company.get_financials()` | Latest annual (10-K) |
|
||||
| `company.get_quarterly_financials()` | Latest quarterly (10-Q) |
|
||||
|
||||
### Financials Object
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `financials.income_statement()` | Income statement |
|
||||
| `financials.balance_sheet()` | Balance sheet |
|
||||
| `financials.cashflow_statement()` | Cash flow |
|
||||
| `financials.get_revenue()` | Revenue scalar |
|
||||
| `financials.get_net_income()` | Net income scalar |
|
||||
| `financials.get_total_assets()` | Total assets scalar |
|
||||
| `financials.get_financial_metrics()` | Dict of all key metrics |
|
||||
|
||||
### Statement Object
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `statement.to_dataframe()` | Convert to DataFrame |
|
||||
| `statement.to_dataframe(view="summary")` | SEC Viewer format |
|
||||
| `statement.to_dataframe(view="standard")` | Filing document format |
|
||||
| `statement.to_dataframe(view="detailed")` | All dimensional breakdowns |
|
||||
|
||||
### Filing-Level (More Control)
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `filing.xbrl()` | Parse XBRL from filing |
|
||||
| `xbrl.statements.income_statement()` | Income statement |
|
||||
| `xbrl.facts.query()` | Query individual facts |
|
||||
|
||||
### Multi-Period
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `XBRLS.from_filings(filings)` | Stitch multiple filings |
|
||||
| `xbrls.statements.income_statement()` | Aligned multi-period |
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "No financial data found"
|
||||
```python
|
||||
filing = company.get_filings(form="10-K").latest()
|
||||
if filing.xbrl():
|
||||
print("XBRL available")
|
||||
else:
|
||||
# Older/smaller companies may not have XBRL
|
||||
text = filing.text() # fallback to raw text
|
||||
```
|
||||
|
||||
### "Statement is empty"
|
||||
Try the detailed view:
|
||||
```python
|
||||
df = income.to_dataframe(view="detailed")
|
||||
```
|
||||
|
||||
### "Numbers don't match SEC website"
|
||||
Check the reporting periods:
|
||||
```python
|
||||
xbrl = filing.xbrl()
|
||||
print(xbrl.reporting_periods)
|
||||
```
|
||||
|
||||
### Accessing financials from a 10-K filing
|
||||
```python
|
||||
# WRONG: filing.financials does not exist
|
||||
filing.financials # AttributeError!
|
||||
|
||||
# CORRECT:
|
||||
tenk = filing.obj()
|
||||
if tenk and tenk.financials:
|
||||
income = tenk.financials.income_statement
|
||||
```
|
||||
373
scientific-skills/edgartools/references/xbrl.md
Normal file
373
scientific-skills/edgartools/references/xbrl.md
Normal file
@@ -0,0 +1,373 @@
|
||||
# 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
|
||||
```
|
||||
Reference in New Issue
Block a user