Dados B3 › Transparency
Transparency
Transparency — how you check the numbers yourself
Data version 2026-11-09-ancora-do-fre · page generated 2026-11-12 08:09 UTC. If these do not match /saude, you are reading a cached copy.
What is checked, before every publication — 1298 automated tests, collected live
28 are DATA invariants (does the number tie out?) and 131 are product tests — access gate, navigation, language, AI connector. Calling all 1298 'invariants' would be inflating it: the split is checkable in the list itself. Not a hand-picked highlight reel: every test below was found by introspecting the actual test files just now, the same way pytest --collect-only would. Grouped by what it protects against, not by which file it lives in.
Level 1 — Integrity: does the data tie out? (21)
DL14— In the connector, events of a company that left the exchange answer without an error, dividends return the error with the left-the-exchange block and no empty list, and an unknown code returns the usual error plus suggestions and the 404 status.DL01— Delisted-company price file reader: only share lines (BDI 02), spot market, class suffix 3-8 or 11 are read, with the same slices as the main price ingest and the quotation factor dividing the QUANTITY, never the price; forward, odd-lot, subscription rights and zero closes are rejected.DL02— The ISIN issuer code is taken only from share (ACN) or unit (CDA) ISINs; ETF, fund and foreign ISINs have none and never enter linking or the gap list.DL06— Building the delisted tables is idempotent: it deletes and rebuilds, so no duplicated sessions and no ticker survives a link that no longer exists.DL07— The list of tables purged when a company leaves the universe excludes the delisted-company tables, otherwise each build would recreate the survivorship bias they exist to fix.DL09— A trading code the company itself declared to the CVM counts even outside the usual format (GOL traded as GOLL54 until 2026) when the B3 quote line is a share; declared rights and undeclared odd codes stay out.DL10— Asking for the dividends of a stock that left the exchange (AESB3, ENBR3) never returns 200 with an empty list: with dividends declared to the CVM it returns them with the left-the-exchange block, otherwise 404 with that block and a retry hint saying the absence is unknown.DL11— A code the database does not have stays 404 with the usual message plus structured suggestions (same root or close spelling, only known codes) so an assistant can retry by itself; retrying with the first suggestion works.DL12— Prices and indicators of a company that left the exchange stay 404, but the error says it left, gives the last trading day and the routes that do answer, and the panel still counts the request.DL13— Corporate events of a company that left the exchange answer 200 with the left-the-exchange block even without a key and a null (not empty) B3 event list; the events declared to the CVM reference form follow the key rule and always carry the no ex-date flag.DL15— A code of a listed company never turns into a company that left the exchange, and a reused code goes to the listed one.DL20— Dividends a delisted company declared in the CVM Reference Form (item 3.5) enter with fiscal year, share class, type, amount and payment date; a re-declared year counts once (newest form), zero amounts and listed companies stay out.DL21— The dividends answer for a company that left returns what it declared to the CVM with the left-the-exchange block and a coverage naming source and period; a company with nothing declared stays 404, never an empty list.DL22— The IPE dividend report of a company that left enters per share with record date, only for ISINs of its own issuer; free-form files are kept without value, nothing is downloaded twice, and an unreachable CVM stops after 5 failures.DL30— The page of a stock that left the exchange (/saiu-da-bolsa/ENBR3, BIDI4, AESB3) opens in Portuguese and English with the direct answer (name, last trading session, total declared to the CVM as a total amount, not per share), the per-year table equal to the JSON /empresas/{T}/dividendos, the CVM code, a citation line with the data version and the page URL, and follows the asset-page rule (English noindex, no hreflang).DL31— On /saiu-da-bolsa every ticker of a company that left links to its own page (or to /acoes/{T} if still in the universe), every such link answers 200, the sitemap has exactly one URL per delisted ticker, and llms.txt cites the per-ticker page with the count.DL32— The English page of a stock that left the exchange has the same numbers, anchors, internal links and table rows as the Portuguese one.DL33— On the synthetic database, the page of a delisted stock with dividends shows the JSON totals and links its other ticker; one with no declared dividend answers 200 saying the absence is unknown, without a table and without linking the 404 dividends route; an active company is 404.DL41— The internal search finds the yearly pages and the main list by deslistagem, OPA, fechamento de capital, cancelamento de registro and saiu da bolsa (the year typed comes first), plus the companies of that year with working links; petz finds the PETZ3 page and AUAU3; the exact code PETZ3 goes straight to its page; /buscar?q= goes to the search; active tickers still go to their own page.DL43— The home block states how many companies left the exchange in the latest year with a page, through the last session date, linking the yearly page and the main list; with no data it says nothing; every page footer links /saiu-da-bolsa.DL44— Performance of a delisted stock (NTCO3) runs up to its last trading day on the as-traded price, without total return, and says distributions are not included
Level 2 — Semantics: does the account mean what the calculation assumes? (7)
DL03— An issuer claimed by two companies through their declared codes is given to neither (no last-wins, no dictionary-order owner); an unambiguous issuer gives its company every share ticker it ever traded under.DL04— End to end on synthetic files: a delisted company gets the code it declared plus the old tickers of the same ISIN issuer, prices stop at each ticker's last session, active companies and their other classes never enter, an unclaimed issuer becomes a gap, an inconsistent OHLC row is kept but flagged, and the old snapshot is rebuilt.DL05— CVM Reference Form splits and reverse splits enter for delisted companies only, once per event (resubmissions do not duplicate), with the declared ratio and the sem_data_ex flag: the form has the approval date, not the ex-date, so it cannot adjust prices.DL08— Delisted coverage is counted from the tables (companies, linked tickers, sessions, declared events, zero dividends because no source exists, gap volume); a database without them reads not built, never zero; the gap table carries class lacuna.DL23— The FRE amount of a company that left is published in reais: when the company typed it in thousands (checked against the DFP net income, which states its scale, or against its own total), it is multiplied by 1,000 and flagged; with nothing to check against it stays as declared.DL40— Each yearly page of companies that left the exchange (/saiu-da-bolsa/{year}) opens in Portuguese and English with the synonyms in title, heading and description (delisting, tender offer, going private, registration cancellation); the count in the direct answer equals the rows and names of the list, the cancellation count equals the second table, 2026 matches the year table of /saiu-da-bolsa, the visible FAQ equals the FAQPage JSON-LD, and the page has the method, primary sources, dividend coverage, its own canonical and the hreflang trio; the sitemap and the main list link every year; a year without a page is 404.DL42— /acoes/{ticker} of a company that left the exchange redirects (301) to its own page, which answers 200; curated ticker changes go to the new ticker; a different successor company stays 404; active and same-company changes are unchanged. The PETZ3 page shows the last per-share dividend (R$ 0.2883, record date 2024-11-13, paid 2024-11-29) equal to the database row, with the CVM filing link, and links AUAU3 as the ticker trading afterwards, with dates checked in the database (consecutive sessions).
Level 3 — Economic: is the result possible in the real world? (0)
Other product tests (0)
Access gate, navigation and the MCP connector — they test whether the product works, not whether a number is right, so they don't fit the 3 levels above by design. Still counted, still listed:
Reconstruct it yourself — net margin across 5 companies, 4 sectors
We don't ask you to trust the numbers. Here's the net margin of five companies in four different sectors, each rebuilt straight from its annual report (DFP) at the CVM — net income ÷ revenue, matching the published figure exactly. For ANY indicator, of any company, the whole chain down to the line in CVM's file is at /linhagem:
| Company · sector | Net income (CVM acct) | Revenue (CVM acct) | Margin =÷ |
|---|---|---|---|
| WEGE3 · industrial | R$ 6.78 bn DRE:3.11 | R$ 40.80 bn DRE:3.01 | 16.6% |
| VALE3 · mining | R$ 11.81 bn DRE:3.11 | R$ 213.59 bn DRE:3.01 | 5.5% |
| PETR4 · oil & gas | R$ 110.61 bn DRE:3.11 | R$ 497.55 bn DRE:3.01 | 22.2% |
| ITUB4 · bank | R$ 45.85 bn DRE:3.09 | R$ 387.12 bn DRE:3.01 | 11.8% |
| BBAS3 · bank | R$ 16.78 bn DRE:3.11 | R$ 319.46 bn DRE:3.01 | 5.3% |
Download any of these DFPs from the CVM, take the income and revenue accounts, divide — you get the same number. Banks use interest income as revenue (what makes sense for a bank), so the reconciliation is sector-aware; the others use sales revenue. Figures are the latest fiscal year.
Why we may differ from another site (and it's not an error)
A difference between two sites usually isn't one being wrong — it's a method choice. We disclose ours:
- Average vs ending capital: ROE and ROIC use average equity/capital (this year + last ÷ 2), not the ending balance — so they're not a naive single-year division.
- Controlling vs consolidated: we state which one each item uses.
- TTM vs annual: quarterly multiples use trailing-twelve-months earnings.
- IFRS 16, goodwill, cash, exceptional tax: each handled explicitly and flagged when it distorts.
Do the tests bite? Yes — real cases the suite has caught
A test that never fails could mean perfect data — or a weak test. These were born from real errors that slipped through, and now fail — only shown for tests that actually exist in the collected suite above:
- I-B16 · banks' P/E = 0: the CVM reports share count sometimes in units, sometimes in thousands (varying by company and year); market cap came out 1000× too small and P/E was zero. I-B16 (price × shares recomputed) caught it — we fixed 661 annual and 2,027 quarterly multiples.
- I-B24 · the vanishing profit: the profit/equity account varies by bank (Itaú 3.09, BB 3.11); if the label search fails, the number vanishes silently and ROE is born wrong. I-B24 makes that hole fail.
- H-B23 · the 800% dividend yield: old B3 dividends carry a price not adjusted for splits; without H-B23 the yield would look absurdly real. The flag keeps the record and warns.
- I-B20 · the missing COTAHIST 2023: on the first deploy one year of prices failed to download silently; the API shipped with ~50k fewer prices and the suite passed, because nothing checked coverage. We added I-B20 — a year without prices now fails the build loudly.
- I-B33 · Oil & Gas at −89.6% in one week: COTAHIST isn't split-adjusted; a 10:1 split read as a −90% weekly return and stayed in the cumulative return forever, with nothing failing (a blind amplitude filter didn't fix it either — it just flipped which direction was wrong). I-B33 (no sector week beyond ±35%, the ruler is the exchange itself) stops the build.
- I-B31 · 364 of 865 sector-index weeks frozen: extending the series back to 2010, a sector with no company carrying a market cap that week turned into a factor of 1.0 — a flat line that the cumulative return read as 'market stood still', and the 'since 2010' return came out fictional (+527%). I-B31 fails on any week repeated to the cent.
- I-E05 · EMBRAER's 2010 P/E priced with 2025 data: the point-in-time price lookup fell forward with no ceiling whenever the current ticker had no price at balance-sheet time (ticker change, share-class migration); the multiple came out priced 15 years into the future, in 22% of annual and quarterly rows, silently. The 45-day window (and I-E05) blocks it: no session inside the deadline, no multiple computed.
- I-E04 · AZUL at R$ 1.67 quadrillion market cap: the balance sheet carried 54.7 trillion shares from the judicial recovery issuance, but the price used was already on the post-reverse-split (1:150,000) basis — two ends measured on different bases, market cap wrong by orders of magnitude. I-E04 (market cap never above Brazil's GDP) fails the build on that absurdity.
How far back each block of data goes
No asterisks here: this is coverage year by year, counted right now. Indicators (ROE, ROIC, margins, growth) come from the filings alone and cover the whole series. Multiples (P/E, P/BV, EV/EBITDA) need a price and a share count — and the share count comes from CVM's reference form, which the further back you go the fewer companies filed in a usable format. The gap between the two columns is a source limit, not an ingestion hole. If you look for an old P/E and do not find it, it is because nobody has it — not because we hid it. The same numbers as JSON: /cobertura.
| Year | Companies with indicators | Companies with multiples |
|---|---|---|
| 2025 | 441 | 290 |
| 2024 | 443 | 296 |
| 2023 | 441 | 298 |
| 2022 | 428 | 295 |
| 2021 | 422 | 296 |
| 2020 | 410 | 274 |
| 2019 | 371 | 166 |
| 2018 | 326 | 167 |
| 2017 | 317 | 165 |
| 2016 | 311 | 154 |
| 2015 | 303 | 144 |
| 2014 | 301 | 140 |
| 2013 | 292 | 131 |
| 2012 | 291 | 112 |
| 2011 | 284 | 98 |
| 2010 | 277 | 34 |
Live coverage
457 companies · 884,647 price points · 8,650 recorded restatements · last refresh 2026-11-12 01:38:24. Full live counts at /saude.
Sources: CVM (open data, ODbL) and B3 (COTAHIST). Not affiliated with B3 or the CVM. Not investment advice.
Numbers on this page are live. Data version 2026-11-09-ancora-do-fre · page generated 2026-11-12 08:09 UTC. If this does not match /saude, you are reading a cached copy.