| Fonte | Dados Obtidos | API/Método | Tipo |
|---|---|---|---|
ticker.income_stmt / quarterly_income_stmt | DRE: Receita, EBIT, EBITDA, Lucro Líquido, etc. | Anual: até 5 períodos; Trimestral: até 5 trimestres | Y Raw |
ticker.cash_flow / quarterly_cash_flow | Fluxo de Caixa: FCF, Operacional, Capex | Anual: até 5 períodos; Trimestral: até 5 trimestres | Y Raw |
ticker.balance_sheet / quarterly_balance_sheet | Balanço: Dívida, PL, Ações, Ativos, Caixa | Anual: até 5 períodos; Trimestral: até 5 trimestres | Y Raw |
ticker.get_info() | Shares Outstanding (fallback), moedas, marketCap, enterpriseValue, TTM snapshot | Valor corrente | Y Raw + Sanity Check |
ticker.history() | Preços históricos de fechamento (diário, 10 anos) | Série temporal | Y Raw |
{MOEDA}USD=X | Taxa de câmbio histórica para USD (diário, 10 anos) | Série temporal | Y Raw |
damodaran_global | Market Cap histórico, EV, múltiplos (cross-validation) | dez/2014–2023 | D |
ticker.get_info(),
porém são apenas um snapshot do momento atual. Não servem para análise histórica.
get_info()| Campo Yahoo | Exemplo (AAPL, mar/2026) | Usado na nossa base? |
|---|---|---|
totalRevenue | $435.6B (TTM corrente) | ❌ Não |
ebitda | $152.9B (TTM corrente) | ❌ Não |
freeCashflow | $106.3B (TTM corrente) | ❌ Não |
trailingPE | 32.22 | ❌ Não |
trailingEps | $7.89 | ❌ Não |
enterpriseToEbitda | 24.43 | ❌ Não (cross-check pontual) |
enterpriseToRevenue | 8.58 | ❌ Não (cross-check pontual) |
O quarterly_income_stmt retorna valores do trimestre individual (não acumulados 12 meses):
| Período | Total Revenue (AAPL) | Natureza |
|---|---|---|
| Q4/2025 | $124.3B | Apenas o trimestre |
| Q3/2025 | $85.8B | Apenas o trimestre |
| Q2/2025 | $94.9B | Apenas o trimestre |
| Q1/2025 | $124.0B | Apenas o trimestre |
| Aspecto | Yahoo get_info() TTM | Nosso TTM calculado |
|---|---|---|
| Cobertura temporal | Apenas 1 ponto (atual) | Até 5 pontos trimestrais (histórico) |
| Série temporal? | ❌ Não | ✅ Sim |
| Análise de tendência? | ❌ Não | ✅ Sim (ex: EBITDA TTM caindo Q-a-Q) |
| Consistência c/ nosso EV | Não garantida | ✅ Usa mesmo EV estimado do período |
| Fonte dos dados | Cálculo interno do Yahoo | Soma dos quarterly_income_stmt |
calculate_ttm.py),
somando os 4 trimestres mais recentes. O Yahoo não fornece TTM histórico via seus demonstrativos trimestrais.
| Componente | Descrição | Fonte |
|---|---|---|
| Pclose(t) | Preço de fechamento diário mais próximo da data do período fiscal | Y ticker.history(period="10y") |
| Fator Subunidade | 100 para LSE (.L, .IL), TASE (.TA), JSE (.JO). Converte pence→GBP, agorot→ILS, cents→ZAR. Para demais exchanges = 1. | C SUBUNIT_EXCHANGES |
| Ordinary Shares Number(t) | Número de ações ordinárias. Fallback: sharesOutstanding via get_info() |
Y balance_sheet |
marketCap reportado pelo Yahoo Finance via get_info().
Se a divergência for > 5x, o valor do YF é usado como fallback.
O campo mcap_quality registra o status:
| mcap_quality | Descrição |
|---|---|
ok | MCap calculado consistente (< 5x divergência do YF) |
mcap_yf_fallback | MCap calculado divergia > 5x do YF — usado o valor do YF |
mcap_yf_only | Sem MCap calculado (sem preço/shares), usado apenas o YF |
no_mcap | Nenhum MCap disponível |
mcap_guard_revenue | MCap/Receita > 50.000× e MCap > 1B — shares provavelmente inflados, MCap zerado |
Critério: Se a diferença entre a data fiscal e o preço mais próximo disponível no Yahoo Finance > 90 dias, o período é classificado como stale_price ou no_historical_price e removido da base.
Impacto (abr/2026): 15.044 registros removidos (5,6% da base), sendo:
no_historical_price: ~11.900 registros em ~4.250 tickers — sem preço disponível no Yahoostale_price: ~1.400 registros em ~1.400 tickers — preço disponível mas >90 dias de defasagemCasos notáveis de migração de ticker (preço irrecuperável):
| Ticker novo | Empresa | Ticker antigo | Status Yahoo |
|---|---|---|---|
| EMBJ3.SA | Embraer | EMBR3.SA | Deletado do Yahoo Finance |
| NATU3.SA | Natura | NTCO3.SA | Deletado do Yahoo Finance |
| NBIS | Nebius (ex-Yandex) | YNDX | Deletado (sanções/reestruturação) |
| TLN | Talen Energy | — | Bankruptcy 2020-2023 |
| SAIL | SailPoint | — | Privatizado 2022-2024 |
Caso resolvido: LTM (LATAM Airlines) — preços FY2022-2023 recuperados via ticker LTM.SN (Santiago, CLP) com conversão CLP→USD antes da remoção.
| Exchange | Problema | Correção Aplicada |
|---|---|---|
| .L / .IL (LSE) | Preços em pence, não libras. MCap inflava ~100x (ex: CNA.L) | Divisão por 100 automática via SUBUNIT_EXCHANGES |
| .TA (TASE, Israel) | Preços em agorot + shares mismatch entre classes. MCap inflava ~3-4x | Divisão por 100 + sanity check vs marketCap do YF |
| .JO (JSE, África do Sul) | Preços em cents, não ZAR | Divisão por 100 automática |
| .JK (Indonésia) | Moeda reportada como USD pelo YF, preço real em IDR | Sanity check detecta divergência ~14.000x, usa marketCap do YF |
| .SN (Chile) | Moeda reportada como USD pelo YF, preço real em CLP | Sanity check detecta divergência ~850x, usa marketCap do YF |
| ADRs (CEPU, EDN) | Preço é do ADR (USD), shares são da empresa local (ex: ARS) | Detecção automática via ratio BS_shares/YF_shares > 3x. Usa shares_outstanding_current do YF |
| Campo | Origem yfinance | Campo no BD | Fonte |
|---|---|---|---|
| Dívida Total | Total Debt | total_debt | Y |
| Caixa e Equivalentes | Cash And Cash Equivalents | cash_and_equivalents | Y |
| Preferred Stock | Preferred Stock | preferred_stock | Y |
| Minority Interest | Minority Interest | minority_interest | Y |
| Preço de Fechamento | ticker.history() | close_price | Y |
| Ações Ordinárias | Ordinary Shares Number | ordinary_shares_number | Y |
| Market Cap Estimado | — | market_cap_estimated | C |
| Enterprise Value Estimado | — | enterprise_value_estimated | C |
| Qualidade MCap | — | mcap_quality | C Audit trail |
Todos os 14 campos abaixo são extraídos diretamente do Yahoo Finance sem nenhuma transformação.
| Campo | Origem yfinance | Campo no BD | Fonte |
|---|---|---|---|
| Receita Total | Total Revenue | total_revenue | Y |
| Custo da Receita | Cost Of Revenue | cost_of_revenue | Y |
| Lucro Bruto | Gross Profit | gross_profit | Y |
| Receita Operacional | Operating Income | operating_income | Y |
| Despesas Operacionais | Operating Expense | operating_expense | Y |
| EBIT | EBIT | ebit | Y |
| EBITDA | EBITDA | ebitda | Y |
| EBITDA Normalizado | Normalized EBITDA | normalized_ebitda | Y |
| Lucro Líquido | Net Income | net_income | Y |
| Despesas de Juros | Interest Expense | interest_expense | Y |
| Provisão p/ IR | Tax Provision | tax_provision | Y |
| P&D | Research And Development | research_and_development | Y |
| SG&A | Selling General And Administration | sga | Y |
| Média Diluída Ações | Diluted Average Shares | diluted_average_shares | Y |
income_stmt.| Campo | Origem yfinance | Campo no BD | Fonte |
|---|---|---|---|
| Free Cash Flow | Free Cash Flow | free_cash_flow | Y |
| Caixa Operacional | Operating Cash Flow | operating_cash_flow | Y |
| Capex | Capital Expenditure | capital_expenditure | Y |
| Campo | Origem yfinance | Campo no BD | Fonte |
|---|---|---|---|
| Dívida Total | Total Debt | total_debt | Y |
| Dívida Curto Prazo | Current Debt | short_term_debt | Y |
| Dívida Longo Prazo | Long Term Debt | long_term_debt | Y |
| Caixa e Equivalentes | Cash And Cash Equivalents | cash_and_equivalents | Y |
| Patrimônio Líquido | Stockholders Equity | stockholders_equity | Y |
| Ações Ordinárias | Ordinary Shares Number | ordinary_shares_number | Y |
| Preferred Stock | Preferred Stock | preferred_stock | Y |
| Minority Interest | Minority Interest | minority_interest | Y |
| Ativos Totais | Total Assets | total_assets | Y |
| Passivos Totais | Total Liabilities Net MI | total_liabilities | Y |
| Investimentos CP | Other Short Term Investments | short_term_investments | Y |
| Ativo Circulante | Current Assets | current_assets | Y |
| Passivo Circulante | Current Liabilities | current_liabilities | Y |
Todos os indicadores desta seção são calculados pela aplicação no fetch_historical_financials.py.
| Indicador | Fórmula | Campo no BD | Fonte |
|---|---|---|---|
| Margem EBIT | EBIT / Receita Total | ebit_margin | C |
| Margem EBITDA | EBITDA / Receita Total | ebitda_margin | C |
| Margem Bruta | Lucro Bruto / Receita Total | gross_margin | C |
| Margem Líquida | Lucro Líquido / Receita Total | net_margin | C |
| Indicador | Fórmula | Campo no BD | Interpretação | Fonte |
|---|---|---|---|---|
| FCF/Receita | FCF / Receita Total | fcf_revenue_ratio | Quanto da receita vira caixa livre | C |
| FCF/EBITDA | FCF / EBITDA | fcf_ebitda_ratio | Eficiência de conversão do EBITDA em caixa | C |
| Capex/Receita | |Capex| / Receita Total | capex_revenue | Intensidade de capital | C |
| Indicador | Fórmula | Campo no BD | Interpretação | Fonte |
|---|---|---|---|---|
| Dívida/PL | Dívida Total / Patrimônio Líquido | debt_equity | Alavancagem financeira | C |
| Dívida/EBITDA | Dívida Total / EBITDA | debt_ebitda | Capacidade de pagamento (em anos de EBITDA) | C |
| Indicador | Fórmula | Campo no BD | Interpretação | Fonte |
|---|---|---|---|---|
| EV/Receita | EV Estimado / Receita Total (ou TTM) | ev_revenue | Múltiplo de receita | C |
| EV/EBITDA | EV Estimado / EBITDA (ou TTM) | ev_ebitda | Múltiplo de EBITDA (principal para valuation) | C |
| EV/EBIT | EV Estimado / EBIT (ou TTM) | ev_ebit | Múltiplo de EBIT | C |
ttm_quarters_count = 4.
Os múltiplos usam o EV estimado do período (não o corrente), permitindo análise temporal.
Script: scripts/calculate_ttm.py
| Tipo | Cálculo TTM | ttm_quarters_count |
|---|---|---|
| Annual | TTM = próprio valor do período (já são 12 meses) | 4 |
| Quarterly | TTM = soma dos 4 últimos trimestres (incluindo o corrente) | 0–4 (real) |
| Campo Trimestral | Campo TTM | Fórmula | Fonte |
|---|---|---|---|
total_revenue | total_revenue_ttm | Σ revenue dos 4Q | C |
ebitda | ebitda_ttm | Σ ebitda dos 4Q | C |
ebit | ebit_ttm | Σ ebit dos 4Q | C |
free_cash_flow | free_cash_flow_ttm | Σ fcf dos 4Q | C |
net_income | net_income_ttm | Σ net_income dos 4Q | C |
| — | ttm_quarters_count | Contagem de Q com dados | C |
period_date[max(0, i-3) .. i] — até 4 registrosNULLttm_quarters_count = trimestres com total_revenue não-nulo na janelaOs múltiplos EV dos registros trimestrais são recalculados com denominadores TTM:
ttm_quarters_count ≥ 4. TTM parcial (< 4Q) → múltiplos NULL.
| Limitação | Impacto |
|---|---|
| Yahoo fornece apenas ~5 trimestres recentes | Primeiro trimestre terá TTM parcial (1-2Q) |
| Ações chinesas/indianas com ~5 trimestres | TTM parcial resulta em subestimação de ~50-75% |
| Trimestres fiscais ≠ calendário | FY em meses não-padrão (mar, jun) podem desalinhar |
| Divergência ~9% entre TTM e anual (mesmo com 4Q) | Normal: diferenças de ajuste contábil Q vs annual |
ticker.get_info()["financialCurrency"] — moeda das demonstrações Yticker.get_info()["currency"] — moeda do preço da ação Y{MOEDA}USD=X com period="10y" Ynearest)fx_rate_to_usdfinancialCurrency ≠ currency (ex: PGAS.JK negocia em IDR, demonstrações em USD),
o Market Cap é convertido automaticamente:trading_currency é salvo separadamente no banco para auditoria.
| Campo Original (moeda local) | Campo USD | Fonte |
|---|---|---|
total_revenue | total_revenue_usd | C |
ebit | ebit_usd | C |
ebitda | ebitda_usd | C |
net_income | net_income_usd | C |
free_cash_flow | free_cash_flow_usd | C |
enterprise_value_estimated | enterprise_value_usd | C |
| Campo | Descrição | Exemplo |
|---|---|---|
original_currency | Moeda das demonstrações financeiras (financialCurrency) | BRL, USD, GBP |
trading_currency | Moeda de negociação do preço (currency) | IDR, CLP, GBp |
fx_rate_to_usd | Taxa de câmbio financialCurrency → USD | 0.17 (BRL→USD) |
subunit_factor | Fator de divisão para exchanges com subunidade (100 para .L, .TA, .JO) | 100 ou NULL |
Várias bolsas cotam preços em subunidades da moeda (ex: pence em vez de libras). O código agora divide automaticamente:
| Sufixo | Exchange | País | Subunidade | Fator |
|---|---|---|---|---|
.L | London Stock Exchange | UK | pence → GBP | ÷100 |
.IL | LSE International | UK | pence → GBP | ÷100 |
.TA | Tel Aviv Stock Exchange | Israel | agorot → ILS | ÷100 |
.JO | Johannesburg Stock Exchange | África do Sul | cents → ZAR | ÷100 |
Exemplo: CNA.L preço = 130 (pence). Antes: MCap = 130 × 5.5B = 715B GBP (errado). Agora: MCap = 1.30 × 5.5B = 7.15B GBP (correto).
SUBUNIT_CURRENCY_MAP)O Yahoo Finance reporta currency em códigos de subunidade (GBp, ILA, ZAc) que diferem de financialCurrency (GBP, ILS, ZAR).
Sem mapeamento, o código tentaria converter entre moedas que são na verdade a mesma (ex: ILA→ILS via câmbio, que não existe).
O mapeamento resolve a moeda subunitária para a principal antes de comparar com financialCurrency:
| Moeda Subunitária | Moeda Principal | Relação |
|---|---|---|
GBp | GBP | 1 GBP = 100 pence |
ILA | ILS | 1 ILS = 100 agorot |
ZAc | ZAR | 1 ZAR = 100 cents |
ADRs (American Depositary Receipts) cotam em USD mas o balanço informa ações locais. Ex: CEPU tem 1.5B ações locais (ARS) mas apenas 150M ADRs (USD). Se usado diretamente, MCap = preço_ADR × ações_locais → inflado pelo ratio ADR (~10x).
Detecção automática: se ordinary_shares_number / shares_outstanding_current > 3, o ticker é classificado como ADR e usa shares_outstanding_current do YF.
Exemplo CEPU: BS shares = 1.5B, YF shares = 150M → ratio 10:1 detectado. Antes: MCap = $14.49 × 1.5B = $21.7B (errado). Agora: MCap = $14.49 × 150M = $2.17B (correto, YF = $2.47B).
marketCap do Yahoo FinancePara períodos recentes (ano fiscal ≥ ano_atual−2), o MCap calculado é comparado com o info["marketCap"] do YF:
marketCap do YF como fallbackmcap_quality registra: ok, mcap_yf_fallback, mcap_yf_only, no_mcap, mcap_guard_revenueNovo campo trading_currency salvo separadamente de original_currency (= financialCurrency):
| Ticker | original_currency | trading_currency | Situação |
|---|---|---|---|
| AAPL | USD | USD | Normal — mesma moeda |
| VALE3.SA | BRL | BRL | Normal — mesma moeda |
| PGAS.JK | USD | IDR | Dif. moedas — conversão automática |
| CNA.L | GBP | GBp | Subunidade — ÷100 automático |
shares_outstanding_currentO sharesOutstanding corrente do YF agora é salvo no banco para auditoria. Permite verificar discrepâncias entre shares históricos (balance sheet) e shares correntes.
| Campo | Tipo | Descrição |
|---|---|---|
trading_currency | TEXT | Moeda de negociação do preço (pode diferir de original_currency) |
shares_outstanding_current | REAL | Shares outstanding correntes do YF (fallback para MCap) |
subunit_factor | REAL | Fator de subunidade aplicado (100 para .L/.TA/.JO, NULL para demais) |
mcap_quality | TEXT | Status do sanity check: ok, mcap_yf_fallback, mcap_yf_only, no_mcap, mcap_guard_revenue. Períodos com no_historical_price ou stale_price são removidos da base (ver seção 3.4) |
| # | Campo no BD | Demonstrativo |
|---|---|---|
| 1-14 | total_revenue, cost_of_revenue, gross_profit, operating_income, operating_expense, ebit, ebitda, normalized_ebitda, net_income, interest_expense, tax_provision, research_and_development, sga, diluted_average_shares | Income Statement |
| 15-17 | free_cash_flow, operating_cash_flow, capital_expenditure | Cash Flow |
| 18-30 | total_assets, total_debt, stockholders_equity, total_liabilities, cash_and_equivalents, short_term_debt, long_term_debt, short_term_investments, current_assets, current_liabilities, ordinary_shares_number, preferred_stock, minority_interest | Balance Sheet |
| 31 | close_price | Preço Histórico |
+ metadata: original_currency, trading_currency, fx_rate_to_usd, subunit_factor, mcap_quality
| Grupo | Campos | Script |
|---|---|---|
| Mercado/EV | market_cap_estimated, enterprise_value_estimated, mcap_quality | fetch |
| Valores USD | total_revenue_usd, ebit_usd, ebitda_usd, net_income_usd, free_cash_flow_usd, enterprise_value_usd | fetch |
| Margens | ebit_margin, ebitda_margin, gross_margin, net_margin | fetch |
| Indicadores | fcf_revenue_ratio, fcf_ebitda_ratio, capex_revenue, debt_equity, debt_ebitda | fetch |
| Múltiplos EV | ev_revenue, ev_ebitda, ev_ebit | fetch + ttm |
| TTM | total_revenue_ttm, ebitda_ttm, ebit_ttm, free_cash_flow_ttm, net_income_ttm, ttm_quarters_count | calculate_ttm |
company_financials_historical — 31 raw + 30 calculados + 4 auditoria.
O yfinance retorna tipicamente:
| Badge | Descrição | Cor |
|---|---|---|
| Períodos | Total de registros | Verde |
| Preço | Registros com close_price > 0 | Verde ≥90%, Amarelo ≥50%, Vermelho <50% |
| Ações | Registros com ordinary_shares_number > 0 | Idem |
| EV | Registros com enterprise_value_estimated | Idem |
| Múltiplos | Registros com ev_revenue calculado | Idem |
| TTM | Registros com total_revenue_ttm | Idem |
| 4Q completos | Registros com ttm_quarters_count ≥ 4 | Idem |
| Limitação | Mitigação |
|---|---|
| Shares Outstanding histórico pode não estar disponível | Usa sharesOutstanding corrente como fallback; salvo em shares_outstanding_current |
| 5° período anual pode ter dados incompletos | Campo data_quality para filtrar |
| Série FX limitada a ~10 anos | Períodos mais antigos usam a taxa mais antiga disponível |
| Yahoo TTM snapshot não usado (apenas snapshot atual) | TTM calculado por soma de 4Q com rastreio de confiabilidade |
| Exchanges com subunidade (pence, agorot, cents) | Divisão automática via SUBUNIT_EXCHANGES + sanity check vs YF |
| Moedas incorretas do YF (IDR→USD, CLP→USD) | Sanity check detecta divergência > 5x e usa marketCap do YF |
| ADRs com shares locais vs preço em USD | Detecção automática via ratio BS/YF shares > 3x, usa shares_outstanding_current |
| Shares mismatch multi-class (Israel .TA) | Subunit fix (÷100) + sanity check vs YF |
Na Base Analítica, cada coluna de dados exibe um indicador sobrescrito:
| Indicador | Tipo | Descrição | Exemplos |
|---|---|---|---|
| 1 | Dado bruto | Extraído diretamente do Yahoo Finance sem transformação | Ações, Preço, Receita, EBITDA, FCF, Dívida, Caixa |
| 2 | Calculado | Derivado pela aplicação a partir dos dados brutos1 | Mkt Cap, EV, Múltiplos, Margens, valores USD |
Campos calculados2 possuem um ícone ℹ no cabeçalho que exibe a fórmula ao passar o mouse.
| Campo | Fórmula | Observação |
|---|---|---|
| Mkt Cap2 | Ações1 × Preço1 | shares_outstanding_current × close_price |
| EV2 | Mkt Cap2 + Dívida1 − Caixa1 | + Preferred Stock + Minority Interest quando disponíveis |
| EV/EBITDA2 | EV2 ÷ EBITDA1 | Apenas quando EBITDA > 0 |
| EV/Vendas2 | EV2 ÷ Receita1 | Apenas quando Receita USD ≥ $100K |
| FCF/Vendas2 | FCF1 ÷ Receita1 | |
| FCF/EBITDA2 | FCF1 ÷ EBITDA1 | |
| Mg EBITDA2 | EBITDA1 ÷ Receita1 | Em % |
| Mg Bruta2 | Lucro Bruto1 ÷ Receita1 | Em % |
| Mg Líq2 | Lucro Líquido1 ÷ Receita1 | Em % |
| Rec USD2 | Receita1 × FX→USD1 | Conversão pela taxa do período |
| EV USD2 | EV2 × FX→USD1 | Conversão pela taxa do período |
| Componente | Fonte | Natureza Temporal |
|---|---|---|
| Preço da ação | Yahoo Finance — preço de fechamento mais recente | Dado atual (mercado) |
| Ações em circulação | Yahoo Finance — get_info() | Dado atual (mercado) |
| Market Cap | Preço atual × Ações atuais | Calculado com dados atuais |
| Dívida, Caixa (p/ EV) | Último balanço disponível (FY2025 ou Q mais recente) | Dado histórico |
| Enterprise Value | Market Cap (atual) + Dívida (hist.) − Caixa (hist.) | Misto: mercado + balanço |
| Receita, EBITDA, FCF | TTM (soma 4Q) ou FY mais recente | Dado histórico/TTM |
| Múltiplos | EV (misto) ÷ Fundamentals (histórico) | Híbrido |
Racional: Para o ano corrente, os demonstrativos financeiros anuais ainda não foram publicados. A melhor estimativa de valor de mercado usa preços e ações atuais, enquanto os denominadores usam dados financeiros recentes (TTM ou FY anterior). Abordagem equivalente a Bloomberg, Capital IQ e Damodaran.
O relatório setorial calcula medianas de EV/EBITDA e EV/Revenue para cada setor, segmentadas por região geográfica (Global, LATAM, Brasil).
normalized_ebitda do Yahoo Finance,
não o campo ebitda. O Normalized EBITDA exclui itens extraordinários e não-recorrentes
(write-offs, ganhos com venda de ativos, reestruturações), evitando distorções nas medianas setoriais.
| Campo | Origem yfinance | Itens Extraordinários | Usado no Relatório |
|---|---|---|---|
ebitda | EBITDA | ✅ Incluídos | ❌ Não |
normalized_ebitda | Normalized EBITDA | ❌ Excluídos | ✅ Sim |
No SQL do relatório:
cfh.normalized_ebitda as ebitda
Para o ano corrente, o relatório combina:
Deduplicação garante 1 registro por empresa, priorizando o trimestral.
Para registros quarterly, os campos-denominador são multiplicados por 4:
| Campo | Ajuste | Racional |
|---|---|---|
normalized_ebitda | ×4 | 1 trimestre → projeção anual |
total_revenue | ×4 | 1 trimestre → projeção anual |
free_cash_flow | ×4 | 1 trimestre → projeção anual |
Os filtros são aplicados em sequência. Empresas excluídas são removidas do dataset (não setadas para NaN), com motivo registrado.
| # | Filtro | Default | Comportamento |
|---|---|---|---|
| 1 | Indústrias selecionadas | Todas | Remove empresas de indústrias não selecionadas |
| 2 | Exclusão manual de tickers | Nenhum | Remove tickers específicos (suporta Exchange:TICKER) |
| 3 | EV mínimo | $100M USD | Remove empresas com EV < limiar |
| 4 | EBITDA positivo | Sim | Remove empresas com EBITDA ≤ 0 ou nulo |
| 5 | Teto EV/EBITDA | 60x | Remove empresas com EV/EBITDA > limiar |
Filtros 3, 4 e 5 são configuráveis pelo usuário na interface.
Apenas quando o denominador é positivo. A métrica principal é EV/EBITDA.
| Estatística | Descrição | Observação |
|---|---|---|
| Mediana | Valor central (menos sensível a outliers) | Métrica principal do relatório |
| Média | Média aritmética | Informativo |
| P25 | Percentil 25 (1° quartil) | Limite inferior |
| P75 | Percentil 75 (3° quartil) | Limite superior |
| N | Contagem de empresas válidas | Representatividade |
Segmentação geográfica:
O relatório calcula spreads (premium/discount) entre regiões: diferença absoluta, percentual e direção.
A evolução aplica a mesma metodologia para cada ano de FY2021 ao FY corrente:
Suíte de testes (scripts/test_data_quality.py) valida a integridade dos dados em múltiplas camadas:
Detecta anomalias no banco de dados:
Simula o cálculo do relatório e verifica:
| Verificação | Descrição |
|---|---|
QUARTERLY_NOT_ANNUALIZED | Detecta se a annualização ×4 está faltando |
CURRENT_YEAR_INFLATED | Mediana do ano corrente > 2× ano anterior |
CEILING_NOT_APPLIED | Mediana > teto configurado |
EXTREME_SECTOR_MEDIAN | Anomalia nas medianas setoriais |
Testes que devem apresentar 0% de desvio — qualquer desvio indica bug:
| Teste | Verificação | Fórmula |
|---|---|---|
| A | Múltiplos armazenados vs calculados | ev_ebitda stored == EV ÷ normalized_ebitda |
| B | Margens armazenadas vs calculadas | ebitda_margin stored == normalized_ebitda ÷ revenue |
| E | Soma de 4 trimestres vs anual | Σ 4Q revenue ≈ annual revenue (mesma empresa, mesmo FY) |
Teste end-to-end que:
/api/estudoanloc/generate_report)Busca dados ao vivo do Yahoo Finance para amostra representativa (10 setores × até 10 tickers) e compara:
fetch_historical_financials.py, calculate_ttm.py, test_data_quality.py