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? (25)
V01— The verdict text is number + numeric band + comparison; no judgement adjective enters, and the 'adjective' mode in the configuration file is OFF — it only turns on by an explicit decision, for the day a licensed analyst signs.V02— The top sentence has at most 25 words and is deterministic: the same input always yields the same sentence, with no language model in the request path.V03— Special cases have their own text and never an invented number: negative profit (P/E does not apply, P/B still does), negative EBITDA, net cash, banks (ROIC and debt/EBITDA do not exist), a young company without history, a value carried with a declared note, a flagged value that is not published, and a multiple flag that belongs to another field.V04— The confidence flag speaks about the SNAPSHOT, with reasons: green when nothing is off; yellow when a central number is withheld by a flag, when a material restatement (≥5% in a key account) happened in the last three years, or when the last annual statement is over 15 months old; red when the snapshot may mislead — the year's own statement was restated by more than 10%, or the regulator already holds a newer statement than the one computed here.V05— The configuration file is coherent with the codebase: every flag it names is produced in precos.py or indicadores.py, the not-applicable map equals the company page's, the forbidden-terms list catches what it must and ignores the standard disclaimer, and the translator never queries the database directly.V06— Run over every traded company: no forbidden term in any text, every top sentence within 25 words, every non-green flag carries a reason, the flag is not uniform (if 90%+ were one colour it would inform nothing), and the same ticker yields the same verdict twice.V07— The 'below the Selic rate' cut for ROIC is switched on and off by the configuration file: off, the fixed band applies; on and with the fiscal year's average Selic, the band says below/at-or-above with the year and the rate; on without that year's Selic, it falls back to the fixed band and never invents the rate. No new label carries a forbidden term.V08— Every cut in the configuration file falls on its declared side: a band's lower limit belongs to it; a zero ROIC with the Selic cut on is 'below', not 'negative'; the company's own history enters with 3 years, not 2; a restatement counts within the last 3 years, from exactly 5%, and only with a known difference; red needs MORE than 10% in the year itself and yellow-by-age MORE than 15 months. Born from the code mutation run of 26/09/2026: each of these comparisons could be flipped and the whole suite still passed.V09— The top sentence is only shortened when it EXCEEDS the word limit, and the cut removes exactly the 'against X for the sector' clause (then the reason for red) — nothing else; zero net debt reads as '0.0x', not net cash; a zero margin with a flag is not narrated as a loss; a FLAGGED number is never narrated as 'not applicable'.V10— The flag text states the filing date and how many central numbers were published, exactly — and the restatement reason quotes the cut as written in the file. The earlier test only checked the start of the sentence, and mutation showed that a date with one extra character or a doubled count went through.V11— The verdict comes out in both languages: the top sentence, the six lines, the questions, the flag (text and reasons) and the note have an English version with the SAME numbers in English format (decimal point), with no Portuguese word; every band, “does not apply” mark, note and Selic band in the configuration has a translation; a bank’s “does not apply” and a caveat do too; no banned term in English.V12— The top sentence of the verdict says the date of the P/E price (the first session after the statements became public) and the P/E at the latest close, plus the sector median, in both languages and within 35 words; the pl and pvp items carry valor_preco_atual and data_preco_atual (same earnings or book value, only the price changes), the text says which is which, and the value stays point-in-time.V13— The P/E at the latest close multiplies the stored multiple by the latest close over the statement-day price and by the share factor of the confirmed events in between (a 2-for-1 split with half the price leaves the P/E equal); an event with no known quantity, or a missing or zero price, leaves the value out and the sentence cites only the point-in-time figure.I-V01— `as_of` on /fatos returns, for each period, the highest filing version whose receipt date is on or before the date asked, with the version and receipt date on every row. The day a version arrived already counts as that version; the day before does not; before the first filing the period does not exist.I-V02— When the version in force on the date asked existed but its values were not kept (the regulator publishes only the latest), the period comes back flagged and WITHOUT numbers — never with the next version's figures, which would be the leak of the future that `as_of` exists to prevent. A database from before the version tables still answers.I-V03— The quarterly `as_of` applies the same rule per year and quarter; annual filings never leak into the quarterly answer.I-V05— Ingestion archives the version about to be overwritten: only the key accounts, only when the incoming version is higher, before the upsert; every version of the filing is kept with its date and document id; re-ingesting or a late older version changes nothing. Annual and quarterly.I-V07— The rule that decides which accounts are kept covers every account the standardisation reads and rejects the ones no item uses: an account forgotten here disappears from the past without a trace.I-V08— A build from scratch loses no versions: what the previous database still holds in a lower version is captured, the history already archived is inherited, a missing or incompatible previous database changes nothing, and the archive count is among the shrink-guarded counts.I-V10— A past version read from the filing XML on the regulator's portal is stored in the same convention as the current version: only the current period, consolidated and individual kept apart, scale applied, both number formats read correctly (with and without the thousands dot), the cash-flow method kept, equity only in the total column, quarterly filings only for the isolated quarter, unused template accounts left out, nothing already stored overwritten, and a file that cannot be read or does not match is counted by reason instead of stopping the load.I-V11— A past version read from the old-format filing file (2020 and earlier) is stored in the same convention as the current version, even though that file names neither the company, the version, the period nor the scale: the document comes from the list and the scale from the total assets the base already holds. Annual filings read the first value column, quarterly ones the second (and the fourth for the first-quarter cash flow and income statement); consolidated and individual stay apart, direct and indirect cash flow stay apart, equity is read only from the current period and the total column, a statement left entirely at zero is not stored as if the company had reported zero, and a file with no total assets to compare, an unclear scale or a layout that contradicts the list is counted by reason instead of being guessed.I-V12— `as_of` on /fatos also picks up the figure RESTATED as a comparative in the next year's annual filing, from the receipt date of that exact filing version (the day before it still returns the original). The row says where the number came from, when it became public and the original value; the old version fields keep describing the company's own filing. Without `as_of` nothing changes.I-V13— A restated comparative replaces the original only for the SAME account: same label, not zeroed in the file, not off by a factor of a thousand, same consolidation basis; a later re-filing of the year itself wins over an earlier comparative; when the version in force has no stored numbers, only the items the already-public comparative covers are returned, never the newest version's figures.I-V14— The /fatos route exposes the origin, public date and source document of each row and the count of restated items on the `as_of` path; without `as_of` the published (original) fact is returned, with no new field.I-V15— Three real restatements from the restatement table (an ordinary company, a bank with its own chart of accounts, another ordinary company): the day before the next annual filing is received the original comes back, the day it is received the restated figure comes back, original and restated never swapped.
Level 2 — Semantics: does the account mean what the calculation assumes? (3)
I-V04— The items rebuilt from an archived version are the SAME ones the standardisation writes from the same accounts, for an ordinary company and for a bank; only the origin gains the version suffix.I-V06— The versions route lists each filing with every version, its date, the link to the original and whether its values are in the base, archived or not kept; between two versions with values it lists only the accounts that changed (before and after).I-V09— The routes: /fatos without `as_of` is unchanged; with `as_of` it answers the version in force; an invalid date is a 422; /versoes lists the filing with both versions and filters the re-filed ones.
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.