Dados B3 › Transparency
Transparency
Transparency — how you check the numbers yourself
Data version 2026-10-01-cfo-metodo-direto · page generated 2026-10-13 15:46 UTC. If these do not match /saude, you are reading a cached copy.
What is checked, before every publication — 653 automated tests, collected live
21 are DATA invariants (does the number tie out?) and 124 are product tests — access gate, navigation, language, AI connector. Calling all 653 '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)
CP01— Thousands and decimal separators follow the language: 1.234.567 and 1.234,57 in PT; 1,234,567 and 1,234.57 in EN; the requested decimal places exactly; HTML escaped.CP02— The verdict flag states its colour through the language label, with the dot in the token colour; text and reasons come out in the language (falling back to PT without an EN version); no reason, no list; everything escaped.CP03— The verdict block: the top sentence, the flag, each question with its items (an unavailable item carries the nd class), the right methodology link for each number in the language, the note, the JSON and the verdict link.CP04— The showcase cell: margin and ROIC in % with 1 decimal, the others with 1 decimal, a dash when unavailable; liquidity in millions; name cut at 28 characters; the flag dot in its colour. The active column header carries the sort arrow and links to the opposite direction; sector and language travel in the link.CP05— The showcase sorts by any column both ways, the flag in the order green, yellow, red; an unknown order becomes ticker; the sector filter is exact; a company without the number goes last in BOTH directions.CP06— The showcase includes companies whose average liquidity is in the window [floor, ceiling) and that have a verdict, in ticker order. The list is kept per data and window version, a new version drops the old one, and without a version nothing is kept.CP07— The showcase page: the window in millions in the intro and the description, the base total, sectors as a filter (the active one in bold, all becomes a link), the count of the filtered table and the default order; PT and EN.CP08— The company watcher page: the list is cut at the configured limit while the N of M count is the total; filters by type and by ticker (upper case); the counter shows only the configured recent months but counts the whole base; dates dd/mm/yyyy (EN yyyy-mm-dd; none, a dash); filter links carry the language; the ticker links to its page in the language.CP09— The fund and ETF watcher pages: their own event types and counter, the ticker linking to /fiis or /etfs, the form with the hidden class, the class JSON, the configured ranges in the text and the class tab in bold; an unknown class is the company one.CP10— /vigia/{T}: the count of all the ticker events in the lede (or the no-event sentence), the type filter with the language, the JSON with the class (none for a company), links to the right ticker page and to all events of the class. The tabs mark the current class and link the others with the language and the week.CP11— On the fund and ETF watcher pages: counter header and type column carry the class labels in the language; dates dd/mm/yyyy in PT; the P/B, yield, vacancy, fee and premium ranges come out WHOLE (one label more than the cut-offs) and configured percentages times 100; an unknown type is ignored; the ticker is cut at 12 characters; with the filter only when filtered.CP12— Values right at the rounding edge: a window of R$ 1,500,000.50 shows as 2 million (not 1); liquidity of R$ 1,050,000.50 as 1.1 mi; an empty sector does not become None. Without sessions in the configuration, the showcase uses and states 63 sessions. The page frame marks the URL section in the menu.CP13— A date with time shows as 15/09/2026 on every watcher page; the ticker filter is cut at 12 characters on the company and ETF pages too; a ticker-only filter already counts as filtered on fund and ETF pages; PT type labels on companies; configured cut-offs at the rounding edge come out by the exact computation.CP14— The share class comes from the last digit (3 ON; 4 to 8 PN; 11 UNT; anything else, none). In the dividend list the ex-date is the first session AFTER the record date (none without a later session); payment date from B3, else from the CVM notice by key (class, record date, value to 6 places), with the source; newest first; the summary counts the last 365 days including the one-year edge and excludes future dates.CP15— P/OCF = market value / operating cash flow; P/FCF = value / (OCF + capex, which is negative); only with positive cash flow (zero does not count); banks, insurers and missing or zero market value get nothing.CP16— Each indicator by theme with round numbers: P/Revenue, EV/Revenue, P/EBITDA and P/EBIT (positive denominator only), EV/EBIT, earnings yield, net debt/equity, gross debt/equity (short plus long; one of them is enough), equity/assets, liabilities/assets, EBITDA margin, turnover, payout and the 5-year CAGRs (both ends positive). Themes in order, an empty theme disappears, banks lose what does not apply.CP17— Sector rank (1 = best, each key in its direction; without a direction rule or with fewer than 3 peers, nothing); the median only with 3+ peers; the year yield = sum / last close of the year; average yield only over the requested years that have one; the record-date radar of the last 5 years from day 1 of the month; the checklist with each threshold and what does not apply to banks; the 12-month snapshot only with a positive denominator.CP18— The rulers half a real away from zero and the thresholds as NUMBERS: 0.50 of cash flow still gives P/OCF; a CAGR end of 0.50; EBITDA, EBIT and revenue of 0.50 to 1.00 still divide; ROE 0.5, yield 0.05 and exactly R$ 10 million of liquidity pass the checklist; zero profit is not profit; a tie in P/E is not better; a past today is used, not the clock.CP19— A synthetic company with round numbers through the whole page path: market value = shares x close; EPS and BVPS on controlling equity; net debt and EV; 12-month yield only from the main class; payout of the fiscal year; P/OCF and P/FCF. Shares in thousands are corrected x1000 and said so; a count outside the [0.02; 50] band of equity gives no market value; banks have no EV. Values in reais, TTM by identity, the 12-month snapshot, liquidity, sector median, returns and the page cache per (version, company).CP20— The market value rulers at exact numbers: shares in thousands only below 1% of controlling equity (exactly 1% is not corrected); the [0.02; 50] band with both ends INSIDE and 50.5 outside. A unit divides the price by its basket; a count jumping 4x without an event gives no market value. Cash and investments published as ZERO count as zero. The 12-month yield counts exactly one year back, not one year and a day. On the page: dividends per year of the main class only, the 8 restatements with the largest absolute difference, the checklist ROE and debt from the fiscal year.CP21— What CP20 did not reach: a 1-year CAGR; the theme block year is the valuation year; controlling equity of 50 cents still passes the band; no dividend in the fiscal year means no dividends of the year; no profit means no payout; EPS of 0.50 still gives payout. In the quarter: cash plus investments, short-term debt only, quarterly and TTM FCF (none when a piece is missing), controlling equity without a minorities line. On the page: 10 years of dividends (not 11), the average yield of the 5 previous full years, roe_ttm really being ROE, and the controlling profit series in the checklist.
Level 2 — Semantics: does the account mean what the calculation assumes? (0)
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 | 440 | 290 |
| 2024 | 444 | 296 |
| 2023 | 442 | 298 |
| 2022 | 429 | 295 |
| 2021 | 423 | 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
456 companies · 878,872 price points · 8,656 recorded restatements · last refresh 2026-10-12 04:46:22. 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-10-01-cfo-metodo-direto · page generated 2026-10-13 15:46 UTC. If this does not match /saude, you are reading a cached copy.