Valuein
All SEC Filing Coverage
20-F
Foreign Private Issuer

Global companies. Same schema.

The 20-F is the 10-K equivalent for foreign companies listed on US exchanges. Alibaba, ASML, Novo Nordisk, Toyota, SAP — these international giants file annually with the SEC. Valuein standardizes their XBRL-tagged financials to the same schema as domestic 10-K filers, so your queries work across the entire universe without case-by-case adjustments.

  • IFRS and US GAAP financials on the same schema
  • ADR and directly-listed foreign companies on US exchanges
  • Cross-listed companies queryable alongside large-cap benchmark members
  • Annual data back to 1993 on Institutional (2011 on Pro)
  • Amendment tracking — 20-F/A restated values preserved

Example 20-F filers in dataset

BABAAlibaba Group
ASMLASML Holding
SAPSAP SE
TMToyota Motor
NVONovo Nordisk
SONYSony Group
SHOPShopify (dual-listed)
RIORio Tinto

Foreign private issuers filing 20-F and 40-F with the SEC are covered on the Institutional tier.

Python SDK

Global equity queries that deliver alpha

Production-ready queries using ValueinClient combining 20-F and 10-K data for cross-border analysis.

Cross-Listed International Revenue Screener

Revenue scale and 2-year growth for every 20-F filer, in each filer's reporting currency. fact has no form type, so the query joins filing on accession_id.

Python
Show the query ↓
valuein_query.pypython
from valuein_sdk import ValueinClient, ValueinError sql = """-- Foreign private issuers file 20-F; the full set is on Pro and Institutional.WITH annual AS (    -- Annual revenue from 20-F filings, latest-filed vintage per year.    -- fact has no form type: join filing on accession_id for it.    SELECT f.entity_id, f.period_end, f.numeric_value, f.reporting_currency    FROM fact f    JOIN filing fi ON fi.accession_id = f.accession_id    WHERE fi.form_type IN ('20-F', '20-F/A')      AND f.standard_concept = 'TotalRevenue'      AND f.fiscal_period = 'FY'    QUALIFY ROW_NUMBER() OVER (        PARTITION BY f.entity_id, f.period_end ORDER BY f.accepted_at DESC    ) = 1),growth AS (    SELECT *,        LAG(numeric_value, 2) OVER (PARTITION BY entity_id ORDER BY period_end) AS revenue_2y_ago    FROM annual    QUALIFY ROW_NUMBER() OVER (PARTITION BY entity_id ORDER BY period_end DESC) = 1)SELECT    r.symbol, r.name, r.sector, r.exchange,    g.period_end,    g.reporting_currency,                          -- values are in this currency    ROUND(g.numeric_value / 1e9, 2)                AS revenue_b,    ROUND(POWER(g.numeric_value / NULLIF(g.revenue_2y_ago, 0), 0.5) - 1, 3) AS cagr_2yrFROM growth gJOIN "references" r ON r.cik = g.entity_id AND r.is_active AND r.is_primary_tickerORDER BY cagr_2yr DESC NULLS LASTLIMIT 30""" try:    with ValueinClient() as client:        df = client.run_query(sql)        print(df)except ValueinError as e:    print(f"Valuein error: {e}")

Global Gross Margin Comparison — 20-F vs 10-K

Latest annual gross margin for Information Technology companies, split by whether the figures came from a 20-F or a 10-K.

Python
Show the query ↓
valuein_query.pypython
from valuein_sdk import ValueinClient, ValueinError sql = """-- Foreign private issuers file 20-F; the full set is on Pro and Institutional.WITH latest AS (    -- Latest annual gross profit and revenue, tagged with the form they came from.    SELECT f.entity_id, f.standard_concept, f.numeric_value, fi.form_type    FROM fact f    JOIN filing fi ON fi.accession_id = f.accession_id    WHERE fi.form_type IN ('10-K', '20-F')      AND f.fiscal_period = 'FY'      AND f.standard_concept IN ('GrossProfit', 'TotalRevenue')    QUALIFY ROW_NUMBER() OVER (        PARTITION BY f.entity_id, f.standard_concept        ORDER BY f.period_end DESC, f.accepted_at DESC    ) = 1),margins AS (    SELECT        entity_id,        CASE WHEN MAX(form_type) = '20-F' THEN 'Foreign private issuer (20-F)'             ELSE 'US domestic (10-K)' END AS listing_type,        MAX(CASE WHEN standard_concept = 'GrossProfit'  THEN numeric_value END)          / NULLIF(MAX(CASE WHEN standard_concept = 'TotalRevenue' THEN numeric_value END), 0) AS gross_margin    FROM latest    GROUP BY entity_id)SELECT    g.listing_type,    COUNT(*)                                AS companies,    ROUND(AVG(g.gross_margin) * 100, 1)     AS avg_gross_margin_pct,    ROUND(MEDIAN(g.gross_margin) * 100, 1)  AS median_gross_margin_pctFROM margins gJOIN "references" r ON r.cik = g.entity_id AND r.is_active AND r.is_primary_tickerWHERE r.sector = 'Information Technology'  AND g.gross_margin BETWEEN 0 AND 1GROUP BY g.listing_type""" try:    with ValueinClient() as client:        df = client.run_query(sql)        print(df)except ValueinError as e:    print(f"Valuein error: {e}")

Operating Cash Flow Quality — International Universe

Free cash flow and its conversion from net income for 20-F filers, from each company's latest fiscal year, in its reporting currency.

Python
Show the query ↓
valuein_query.pypython
from valuein_sdk import ValueinClient, ValueinError sql = """-- Foreign private issuers file 20-F; the full set is on Pro and Institutional.WITH annual AS (    SELECT f.entity_id, f.period_end, f.standard_concept, f.numeric_value, f.reporting_currency    FROM fact f    JOIN filing fi ON fi.accession_id = f.accession_id    WHERE fi.form_type IN ('20-F', '20-F/A')      AND f.fiscal_period = 'FY'      AND f.standard_concept IN ('OperatingCashFlow', 'CAPEX', 'NetIncome')    QUALIFY ROW_NUMBER() OVER (        PARTITION BY f.entity_id, f.standard_concept, f.period_end ORDER BY f.accepted_at DESC    ) = 1),latest AS (    SELECT        entity_id,        period_end,        ANY_VALUE(reporting_currency)                                                AS currency,        MAX(CASE WHEN standard_concept = 'OperatingCashFlow' THEN numeric_value END) AS ocf,        MAX(CASE WHEN standard_concept = 'CAPEX'             THEN numeric_value END) AS capex,        MAX(CASE WHEN standard_concept = 'NetIncome'         THEN numeric_value END) AS net_income    FROM annual    GROUP BY entity_id, period_end    HAVING ocf IS NOT NULL AND capex IS NOT NULL    QUALIFY ROW_NUMBER() OVER (PARTITION BY entity_id ORDER BY period_end DESC) = 1)SELECT    r.symbol, r.name, r.sector, r.exchange,    l.period_end,    l.currency,                                              -- values are in this currency    ROUND(l.ocf / 1e9, 2)                                    AS cfo_b,    ROUND(ABS(l.capex) / 1e9, 2)                             AS capex_b,    ROUND((l.ocf - ABS(l.capex)) / 1e9, 2)                   AS fcf_b,    ROUND(l.net_income / 1e9, 2)                             AS net_income_b,    ROUND((l.ocf - ABS(l.capex)) / NULLIF(l.net_income, 0), 2) AS fcf_conversionFROM latest lJOIN "references" r ON r.cik = l.entity_id AND r.is_active AND r.is_primary_tickerORDER BY fcf_conversion DESC NULLS LASTLIMIT 20""" try:    with ValueinClient() as client:        df = client.run_query(sql)        print(df)except ValueinError as e:    print(f"Valuein error: {e}")

Debt Structure Comparison — Global Industrials

Leverage for domestic and foreign industrial filers. IFRS lease accounting and US GAAP produce visibly different capital structures — surface the gap programmatically.

Python
Show the query ↓
valuein_query.pypython
from valuein_sdk import ValueinClient, ValueinError sql = """-- Foreign private issuers file 20-F; the full set is on Pro and Institutional.-- Amounts are in each filer's reporting currency (reporting_currency on fact).WITH latest AS (    SELECT f.entity_id, f.standard_concept, f.numeric_value, fi.form_type    FROM fact f    JOIN filing fi ON fi.accession_id = f.accession_id    WHERE fi.form_type IN ('10-K', '20-F')      AND f.fiscal_period = 'FY'      AND f.standard_concept IN ('LongTermDebt', 'StockholdersEquity', 'TotalAssets')    QUALIFY ROW_NUMBER() OVER (        PARTITION BY f.entity_id, f.standard_concept        ORDER BY f.period_end DESC, f.accepted_at DESC    ) = 1),leverage AS (    SELECT        entity_id,        CASE WHEN MAX(form_type) = '20-F' THEN 'International' ELSE 'US' END AS universe,        MAX(CASE WHEN standard_concept = 'LongTermDebt'       THEN numeric_value END) AS long_term_debt,        MAX(CASE WHEN standard_concept = 'StockholdersEquity' THEN numeric_value END) AS equity,        MAX(CASE WHEN standard_concept = 'TotalAssets'        THEN numeric_value END) AS total_assets    FROM latest    GROUP BY entity_id)SELECT    r.symbol, r.name, r.exchange,    l.universe,    ROUND(l.long_term_debt / NULLIF(l.equity, 0), 2) AS debt_to_equity,    ROUND(l.long_term_debt / 1e9, 2)                 AS long_term_debt_b,    ROUND(l.total_assets / 1e9, 1)                   AS total_assets_bFROM leverage lJOIN "references" r ON r.cik = l.entity_id AND r.is_active AND r.is_primary_tickerWHERE r.sector = 'Industrials'  AND l.total_assets > 5e9ORDER BY debt_to_equity ASC NULLS LAST""" try:    with ValueinClient() as client:        df = client.run_query(sql)    print(df.groupby("universe")["debt_to_equity"].describe())except ValueinError as e:    print(f"Valuein error: {e}")
MCP Server

Global research with AI

Ask Claude to compare international companies against domestic peers, surface undervalued ADRs by sector, or analyze revenue trends for specific cross-listed companies — all from your 20-F dataset.

›Compare revenue growth for the top 20 ADR companies vs their S&P 500 sector peers in 2024
›Which foreign private issuers in the Technology sector have higher operating margins than the S&P 500 average?
›Show me the FCF conversion ratio for all 20-F filers with revenue over $10 billion
›What is Toyota's revenue trend over the last 5 years from 20-F filings?

Add international coverage to your strategy

Pro and Institutional include 20-F and 40-F foreign private issuers alongside the full universe of 28,000+ companies. Institutional history runs to 1993 and Pro to 2011. The free Benchmark tier does not include foreign issuers.

Index names are trademarks of their owners; Valuein is not affiliated with or endorsed by any index provider.