一键导入
financials
Extract structured financials from Icelandic annual report PDFs using Docling — income statement, balance sheet, cash flow, ratios.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Extract structured financials from Icelandic annual report PDFs using Docling — income statement, balance sheet, cash flow, ratios.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Iceland energy authority — electricity generation, use, fuel sales, power plants and licences. Use for energy-system analysis.
Fiskistofa — public WFS layers for fishing closures, regulations and fishing areas; paid REST catch/quota data is excluded.
Hafrannsóknastofnun / MFRI — annual fish-stock assessments, advice, landings and survey series in embedded tables.
Environment Agency of Iceland GIS — open WFS layers for contaminated land, water, protected areas, noise and wastewater.
Icelandic Met Office (Veðurstofa) — weather observations, stations, forecasts and earthquakes via the modern JSON API at api.vedur.is.
Iceland Tax Authority — annual reports (ársreikningar), company registry, ownership chain mapping by kennitala.
| name | financials |
| description | Extract structured financials from Icelandic annual report PDFs using Docling — income statement, balance sheet, cash flow, ratios. |
Extract structured financial data from Icelandic annual reports (ársreikningar) using AI-powered PDF parsing.
This skill combines:
Company kennitala
↓
skatturinn.py download (PDF)
↓
Docling (markdown + tables)
↓
Claude (structured JSON)
↓
Standardized financial data
interface CompanyFinancials {
// Identification
company_name: string;
kennitala: string;
fiscal_year: number;
report_type: "full" | "hnappurinn" | "consolidated";
// Income Statement (Rekstraryfirlit)
income: {
revenue: number; // Rekstrartekjur
operating_expenses: number; // Rekstrargjöld
ebitda: number; // Afkoma fyrir afskriftir
depreciation: number; // Afskriftir
ebit: number; // Afkoma fyrir fjármagnsliði
financial_income: number; // Fjármunatekjur
financial_expenses: number; // Fjármagnsgjöld
profit_before_tax: number; // Afkoma fyrir skatt
income_tax: number; // Tekjuskattur
net_profit: number; // Hagnaður/Tap ársins
};
// Balance Sheet (Efnahagsyfirlit)
balance: {
// Assets (Eignir)
fixed_assets: number; // Fastafjármunir
current_assets: number; // Veltufjármunir
total_assets: number; // Eignir samtals
// Equity & Liabilities
share_capital: number; // Hlutafé
retained_earnings: number; // Óráðstafað eigið fé
total_equity: number; // Eigið fé samtals
long_term_debt: number; // Langtímaskuldir
short_term_debt: number; // Skammtímaskuldir
total_liabilities: number; // Skuldir samtals
};
// Cash Flow (if available)
cashflow?: {
operating: number; // Handbært fé frá rekstri
investing: number; // Fjárfestingarhreyfingar
financing: number; // Fjármögnunarhreyfingar
net_change: number; // Breyting á handbæru fé
};
// Ownership (from skatturinn page or PDF)
ownership: Array<{
name: string;
kennitala?: string; // If company owner
birth_year_month?: string; // If individual (privacy)
percentage: number;
type: "direct" | "indirect";
}>;
// Corporate Structure
parent_company?: {
name: string;
kennitala: string;
ownership_pct: number;
};
subsidiaries: Array<{
name: string;
kennitala: string;
ownership_pct: number; // How much THIS company owns
book_value?: number; // Bókfært virði
equity_method: boolean; // Hlutdeildaraðferð (20-50% ownership)
}>;
associates: Array<{ // Hlutdeildarfélög (20-50% ownership)
name: string;
kennitala: string;
ownership_pct: number;
book_value?: number;
}>;
// Key Metrics (calculated)
metrics: {
equity_ratio: number; // Eiginfjárhlutfall
current_ratio?: number; // Veltufjárhlutfall
debt_to_equity?: number; // Skuldir/Eigið fé
profit_margin?: number; // Hagnaðarhlutfall
};
// Notable Events
events: Array<{
type: "acquisition" | "investment" | "dividend" | "restructuring" | "other";
description: string;
amount?: number;
}>;
// Data Quality
extraction: {
source_pdf: string;
extracted_at: string;
confidence: "high" | "medium" | "low";
notes: string[];
};
}
Banks have a different financial structure than commercial companies:
interface BankFinancials {
bank_name: string;
kennitala: string;
fiscal_year: number;
report_type: "parent" | "consolidated" | "quarterly";
// Income Statement (different from commercial companies)
income: {
interest_income: number; // Vaxtatekjur
interest_expense: number; // Vaxtagjöld
net_interest_income: number; // Hreinar vaxtatekjur (KEY METRIC)
fee_income: number; // Þóknanatekjur
fee_expense: number; // Þóknanagjöld
net_fee_income: number; // Hreinar þóknanatekjur
total_operating_income: number; // Rekstrartekjur samtals
total_operating_expense: number;// Rekstrarkostnaður
bank_tax: number; // Sérstakur skattur á fjármálafyrirtæki
impairment: number; // Virðisrýrnun
net_profit: number; // Hagnaður
};
// Balance Sheet
balance: {
loans_to_customers: number; // Lán til viðskiptavina
deposits_from_customers: number;// Innlán frá viðskiptavinum
total_assets: number; // Eignir samtals
total_equity: number; // Eigið fé samtals
};
// Regulatory Capital (Basel III)
capital: {
cet1_ratio: number; // CET1 hlutfall
tier1_ratio: number; // Eiginfjárþáttur 1
total_car: number; // Eiginfjárhlutfall (CAR)
rwa: number; // Áhættugrunnar (Risk-Weighted Assets)
lcr: number; // Lausafjárþekjuhlutfall
nsfr: number; // Fjármögnunarhlutfall
};
// Key Metrics
metrics: {
roe: number; // Return on Equity
nim: number; // Net Interest Margin (KEY)
cost_income_ratio: number; // Kostnaðarhlutfall
npl_ratio: number; // Non-performing loans
dividend_total: number; // Total dividends paid
buybacks: number; // Share repurchases
payout_ratio: number; // Dividend + buybacks / profit
};
}
| Icelandic | English | Schema Field |
|---|---|---|
| Rekstrartekjur | Revenue | income.revenue |
| Rekstrargjöld | Operating expenses | income.operating_expenses |
| Afskriftir | Depreciation | income.depreciation |
| Fjármunatekjur | Financial income | income.financial_income |
| Fjármagnsgjöld | Financial expenses | income.financial_expenses |
| Tekjuskattur | Income tax | income.income_tax |
| Hagnaður ársins | Net profit | income.net_profit |
| Fastafjármunir | Fixed assets | balance.fixed_assets |
| Veltufjármunir | Current assets | balance.current_assets |
| Hlutafé | Share capital | balance.share_capital |
| Eigið fé | Equity | balance.total_equity |
| Langtímaskuldir | Long-term debt | balance.long_term_debt |
| Skammtímaskuldir | Short-term debt | balance.short_term_debt |
| Arðgreiðslur | Dividends | events (type: dividend) |
| Dótturfélög | Subsidiaries | subsidiaries[] |
| Hlutdeildarfélög | Associates (20-50%) | associates[] |
| Móðurfélag | Parent company | parent_company |
| Eignarhlutir í dótturfélögum | Shares in subsidiaries | subsidiaries[].book_value |
| Samstæða | Group/Consolidated | report_type: "consolidated" |
# Extract financials from a downloaded PDF
uv run python scripts/financials.py extract /path/to/report.pdf
# Full pipeline: download + extract for a company
uv run python scripts/financials.py company 5012043070 --year 2024
# Output as JSON
uv run python scripts/financials.py company 5012043070 --year 2024 --format json
Banks have different financial statement structures. Use the --bank flag or dedicated bank command:
# Extract bank financials from PDF (local file)
uv run python scripts/financials.py extract /path/to/arion_2024.pdf --bank
# Full pipeline for banks
uv run python scripts/financials.py bank 5810080150 --year 2024 # Arion
uv run python scripts/financials.py bank 4910083880 --year 2024 # Íslandsbanki
uv run python scripts/financials.py bank 4710044100 --year 2024 # Landsbankinn
# Output JSON schema for banks
uv run python scripts/financials.py bank-schema
| Bank | Kennitala |
|---|---|
| Arion banki hf. | 5810080150 |
| Íslandsbanki hf. | 4910083880 |
| Landsbankinn hf. | 4710044100 |
| Kvika banki hf. | 5407992500 |
uv sync
# Docling downloads models on first run (~500MB)
from docling.document_converter import DocumentConverter
def extract_pdf(pdf_path: str) -> tuple[str, list[dict]]:
"""Extract markdown and tables from PDF."""
converter = DocumentConverter()
result = converter.convert(pdf_path)
markdown = result.document.export_to_markdown()
tables = []
for table in result.document.tables:
tables.append({
"dataframe": table.export_to_dataframe().to_dict(),
})
return markdown, tables
Docling's TableFormer model handles:
After Docling extracts the content, use Claude to interpret and standardize:
EXTRACTION_PROMPT = '''
Extract structured financial data from this Icelandic annual report.
DOCUMENT:
{markdown}
TABLES:
{tables_json}
Return a JSON object matching this schema:
{schema}
Guidelines:
1. All amounts in ISK (Icelandic króna), no thousands separators
2. Negative values for expenses/losses (use actual signs from document)
3. Calculate metrics if raw data available
4. Note any unusual items in events[]
5. Set confidence based on data completeness
6. If "Hnappurinn" format, mark report_type accordingly
Return ONLY valid JSON, no markdown.
'''
Currency: All figures in ISK. Watch for thousands (þús.kr.) vs millions (m.kr.) notation.
Fiscal Year: Most companies use calendar year, but some differ. Check "Reikningsár" field.
Comparatives: Reports show current year + prior year. Extract both for trend analysis.
Rounding: Hnappurinn reports often round to thousands. Full reports may have exact figures.
Negative Signs: Expenses sometimes shown as positive numbers with context, sometimes with parentheses or minus signs.
from scripts.skatturinn import download_annual_report, get_company_info
from scripts.financials import extract_financials
async def get_company_financials(kennitala: str, year: int):
"""Full pipeline: fetch PDF, extract, standardize."""
# Get company info (includes ownership from page)
info = await get_company_info(kennitala)
# Download the PDF
pdf_path = await download_annual_report(kennitala, year)
# Extract with Docling + Claude
financials = extract_financials(pdf_path, info)
return financials
Store extracted financials in /data/processed/financials/:
/data/processed/financials/
/{kennitala}/
/2024.json # Full extracted data
/2023.json
/summary.csv # Multi-year comparison
SQL queries in /evidence-reports/sources/financials/:
-- company_trends.sql
SELECT
fiscal_year,
income_revenue,
income_net_profit,
balance_total_equity,
metrics_equity_ratio
FROM read_json_auto('../data/processed/financials/5012043070/*.json')
ORDER BY fiscal_year
| Data | Source | Method |
|---|---|---|
| Parent company | skatturinn page | Beneficial owners with company kennitala |
| Subsidiaries | Annual report PDF | Notes section, "Eignarhlutir í dótturfélögum" |
| Associates | Annual report PDF | "Hlutdeildarfélög" section |
| Group structure | Recursive lookup | Follow kennitalas both directions |
From skatturinn ownership scraping, if a beneficial owner has a company kennitala (starts with 4-7), that's a parent company:
for owner in company.beneficial_owners:
if owner.is_company: # kennitala[0] in "4567"
financials.parent_company = {
"name": owner.name,
"kennitala": owner.kennitala,
"ownership_pct": owner.ownership_pct
}
Look for these patterns in annual report notes:
Eignarhlutir í dótturfélögum:
| Nafn | Kennitala | Eignarhlutur | Bókfært virði |
|------|-----------|--------------|---------------|
| ABC ehf. | 1234567890 | 100% | 50.000.000 |
Also check balance sheet line "Eignarhlutir í dóttur- og hlutdeildarfélögum" - if > 0, there are subsidiaries.
| Ownership % | Classification | Accounting |
|---|---|---|
| >50% | Dótturfélag (Subsidiary) | Full consolidation |
| 20-50% | Hlutdeildarfélag (Associate) | Equity method |
| <20% | Fjárfesting (Investment) | Cost/fair value |
async def build_group_structure(root_kennitala: str) -> dict:
"""
Build complete group structure:
- Look UP: find parent companies
- Look DOWN: find subsidiaries
"""
company = await get_company_financials(root_kennitala)
structure = {
"company": company,
"parents": [],
"subsidiaries": []
}
# Look UP - parent from beneficial owners
if company.parent_company:
parent_structure = await build_group_structure(
company.parent_company.kennitala
)
structure["parents"].append(parent_structure)
# Look DOWN - subsidiaries from notes
for sub in company.subsidiaries:
sub_structure = await build_group_structure(sub.kennitala)
structure["subsidiaries"].append(sub_structure)
return structure
# Get company with parent/subsidiary info
uv run python scripts/financials.py company 5012043070 --include-structure
# Build full group tree
uv run python scripts/financials.py group 5012043070 --depth 3
# Find ultimate parent (top of chain)
uv run python scripts/financials.py ultimate-parent 5012043070