Skip to main content

etl-ativa-investimentos

PyPI

Biblioteca Python para leitura dos arquivos Excel exportados pela corretora Ativa Investimentos, convertendo-os em pandas.DataFrame prontos para análise, pipelines de dados e integrações ETL.


Instalação

pip install etl-ativa-investimentos

Requisitos: Python >= 3.11


Motivação

A Ativa Investimentos exporta relatórios em Excel com múltiplas abas e nomes de colunas hostis a uso programático (acentuação inconsistente, espaços duplicados, typos). Esta biblioteca abstrai a leitura desses arquivos, entregando DataFrames com colunas em snake_case pythônico e tipos coagidos — sem precisar se preocupar com nomes de abas, encoding, engine de leitura ou o de-para das colunas.


Normalização de colunas

Por padrão, todo read_* devolve colunas normalizadas: snake_case, minúsculas, sem acentos, sem espaços — e colunas numéricas já coagidas (ex.: qtd, que no Excel vem como texto no formato pt-BR "1.500,00").

df = carteira_cotizada.read_carteira_analitica(path)
df.columns  # Index(['mercado', 'ativo', 'qtd', 'pu_custo', ...])
df["qtd"].dtype  # float64

Para acessar o dado exatamente como está no Excel (nomes originais, sem coerção de tipo), use raw=True:

df_raw = carteira_cotizada.read_carteira_analitica(path, raw=True)
df_raw.columns  # Index(['Mercado', 'Ativo', 'QTD', 'PU Custo', ...])
df_raw["QTD"].dtype  # object (string "100", "26,00", ...)

O de-para completo (coluna crua → coluna canônica) de cada aba está documentado em docs/*.md e implementado em normalize.py.


Módulos

A lib é organizada por tipo de relatório. Cada módulo expõe:

  • Funções individuais por aba: read_<nome_da_aba>(path)
  • Uma função read_all(path) que retorna todas as abas como dict[str, DataFrame]

posicao_consolidada

Lê o relatório de Posição Consolidada (.xls), disponível no portal da corretora.

from etl_ativa_investimentos import posicao_consolidada

path = "posicao_consolidada/2025_12_30.xls"

# Aba individual
df_acoes = posicao_consolidada.read_acoes(path)
df_rf    = posicao_consolidada.read_renda_fixa_privada(path)

# Todas as abas de uma vez
data = posicao_consolidada.read_all(path)
Função Aba do Excel Colunas principais (normalizadas)
read_acoes(path) Ações codigo, nome, carteira, quantidade, preco, total
read_clubes_e_fundos(path) Clubes e Fundos nome_do_fundo, data, valor_da_aplicacao, cota, valor
read_financeiro(path) Financeiro conta, tipo, disponivel, projecao_liquidacao, total
read_renda_fixa_privada(path) Renda Fixa Privada ticker, emissor, remuneracao, pu_atual, quantidade, total
read_renda_fixa_publica(path) Renda Fixa Pública titulo, emissor, indexador, data_vencimento, pu_atual, total
read_all(path) Todas Retorna dict[str, DataFrame]

Todas aceitam raw: bool = False — veja Normalização de colunas.

Chaves retornadas por read_all:

{
    "acoes": ...,
    "clubes_e_fundos": ...,
    "financeiro": ...,
    "renda_fixa_privada": ...,
    "renda_fixa_publica": ...,
}

carteira_cotizada

Lê o relatório de Carteira Cotizada / Painel (.xlsx), exportado pelo sistema SIM da corretora.

from etl_ativa_investimentos import carteira_cotizada

path = "SIM.PAINEL.2026.01.30.10.01.36.xlsx"

# Aba individual
df = carteira_cotizada.read_carteira_analitica(path)

# Todas as abas de uma vez
data = carteira_cotizada.read_all(path)
Função Conteúdo
read_variacao_patrimonial(path) Patrimônio bruto, líquido e variação percentual
read_composicao_patrimonio(path) Composição por classe de ativo com provisões de IR e IOF
read_carteira_analitica(path) Posição consolidada com preços, financeiros e L/P (qtd numérico)
read_rentabilidade_carteira(path) Performance: dia, mês, 30 dias, ano, 12 meses, início
read_rentabilidade_no_ano(path) Rentabilidade mensal no ano corrente por ativo (colunas jandez)
read_rentabilidade_ultimos_meses(path) Histórico mensal comparado ao CDI e IBOVESPA (colunas YYYY_MM)
read_rentabilidade_ativos(path) Performance individual por ativo em múltiplos períodos
read_provisoes(path) Provisões de IR e IOF com datas e valores
read_renda_fixa_detalhada(path) CDBs e títulos com PU de aquisição, atual, IR e IOF
read_clubes_e_fundos_detalhados(path) Fundos com cotas, L/P, IR, IOF e valor líquido
read_all(path) Todas as abas — retorna dict[str, DataFrame]

Todas aceitam raw: bool = False — veja Normalização de colunas.

Chaves retornadas por read_all:

{
    "variacao_patrimonial": ...,
    "composicao_patrimonio": ...,
    "carteira_analitica": ...,
    "rentabilidade_carteira": ...,
    "rentabilidade_no_ano": ...,
    "rentabilidade_ultimos_meses": ...,
    "rentabilidade_ativos": ...,
    "provisoes": ...,
    "renda_fixa_detalhada": ...,
    "clubes_e_fundos_detalhados": ...,
}

movimentacao_b3

Lê o relatório de Movimentação B3 (.xlsx), exportado diretamente pelo portal da B3 ou pela corretora.

from etl_ativa_investimentos import movimentacao_b3

path = "movimentacao-2023-01-01-ate-31-12-2023.xlsx"

# Aba individual
df = movimentacao_b3.read_movimentacao(path)

# Todas as abas de uma vez
data = movimentacao_b3.read_all(path)
Função Aba do Excel Colunas principais (normalizadas)
read_movimentacao(path) Movimentação entrada_saida, data, movimentacao, produto, instituicao, quantidade, preco_unitario, valor_da_operacao
read_all(path) Todas Retorna dict[str, DataFrame]

Todas aceitam raw: bool = False — veja Normalização de colunas.

Chaves retornadas por read_all:

{
    "movimentacao": ...,
}

Tratamento de erros

Falhas de leitura são levantadas como exceções próprias da lib, todas em etl_ativa_investimentos.exceptions e derivadas de EtlAtivaError. Isso permite capturar qualquer falha da lib com um único except e repassar uma mensagem amigável ao usuário final (ex.: numa view Django).

from etl_ativa_investimentos import carteira_cotizada
from etl_ativa_investimentos.exceptions import (
    EtlAtivaError,
    InvalidExcelFileError,
    SheetNotFoundError,
)

try:
    df = carteira_cotizada.read_carteira_analitica(arquivo_enviado)
except SheetNotFoundError as e:
    # e.report, e.sheet -- útil para logging estruturado
    return HttpResponseBadRequest(str(e))
except InvalidExcelFileError as e:
    return HttpResponseBadRequest(str(e))
except EtlAtivaError as e:
    # qualquer outra falha da lib
    return HttpResponseBadRequest(str(e))
Exceção Quando ocorre
EtlAtivaError Classe base — nunca levantada diretamente, use para capturar qualquer falha da lib
SheetNotFoundError A aba esperada não existe no arquivo — geralmente indica que o arquivo é de outro relatório (ex.: passar uma Movimentação B3 para carteira_cotizada.read_*), ou que o layout do relatório da Ativa mudou. Expõe .report e .sheet.
InvalidExcelFileError O arquivo não pôde ser interpretado como Excel (corrompido, formato incompatível, ou não é um Excel de verdade). Expõe .report.

Interface orientada a objetos (readers)

Além das funções funcionais, a lib oferece classes que encapsulam leitura, cache e validação:

from etl_ativa_investimentos.readers.carteira_cotizada import CarteiraCotizada
from etl_ativa_investimentos.readers.posicao_consolidada import PosicaoConsolidada
from etl_ativa_investimentos.readers.movimentacao_b3 import MovimentacaoB3

Cada classe segue o mesmo contrato:

Método Descrição
.<aba>(raw=False) Retorna o DataFrame da aba (lazy load + cache, separado por raw)
.<aba>_entities() Retorna list[EntidadeTipada] — a aba convertida em dataclasses
.infer_excel_date() Tenta inferir a data do Excel pelo nome do arquivo; retorna date ou None
.load() Carrega todas as abas em memória de uma vez
.validate_all() Valida todas as abas (contra o DataFrame normalizado); retorna ValidationResult
.load_and_print_errors() Carrega, valida e exibe erros formatados

Exemplo

from etl_ativa_investimentos.readers.carteira_cotizada import CarteiraCotizada

carteira = CarteiraCotizada("SIM.PAINEL.2026.01.30.10.01.36.xlsx")

# Inferência da data a partir do nome do arquivo (YYYY.MM.DD)
excel_date = carteira.infer_excel_date()
print(excel_date)  # 2026-01-30

# Lazy load — lê só quando chamado, resultado fica em cache
df = carteira.carteira_analitica()

# Validação estruturada
result = carteira.validate_all()
if not result.ok:
    print(result.errors)  # {"nome_aba": ["mensagem de erro", ...]}

# Ou de forma conveniente
carteira.load_and_print_errors()

Entidades tipadas

Além do DataFrame, cada aba pode ser obtida como list[dataclass] — útil para passar adiante (ex.: para um app Django) sem expor pandas na fronteira.

carteira = CarteiraCotizada("SIM.PAINEL.2026.01.30.10.01.36.xlsx")

ativos = carteira.carteira_analitica_entities()  # list[CarteiraAnaliticaEntity]
ativos[0].ativo, ativos[0].qtd, ativos[0].pu_atual

As entidades são dataclass(frozen=True, slots=True), definidas em entities/<modulo>.py, com campos espelhando os nomes canônicos (ver Normalização de colunas). Abas com colunas dinâmicas (rentabilidade_no_ano, rentabilidade_ultimos_meses) agrupam essas colunas num campo valores: dict[str, float].

Pydantic (opcional)

Por padrão as entidades são dataclasses puras — zero dependência extra. Para validação/serialização com pydantic, instale o extra e use as_pydantic:

pip install etl-ativa-investimentos[pydantic]
from etl_ativa_investimentos.entities._convert import as_pydantic
from etl_ativa_investimentos.entities.carteira_cotizada import CarteiraAnaliticaEntity

CarteiraAnaliticaModel = as_pydantic(CarteiraAnaliticaEntity)
CarteiraAnaliticaModel(**dados)  # valida e levanta pydantic.ValidationError se inválido

as_pydantic decora o dataclass existente em vez de duplicar a definição — nome e tipo de cada campo continuam vindo de uma única fonte.


Exemplo completo (API funcional)

from etl_ativa_investimentos import (
    posicao_consolidada,
    carteira_cotizada,
    movimentacao_b3,
)

# Posição consolidada
posicao = posicao_consolidada.read_all("posicao_consolidada/2025_12_30.xls")
print(posicao["acoes"])

# Carteira cotizada
painel = carteira_cotizada.read_all("SIM.PAINEL.2026.01.30.10.01.36.xlsx")
print(painel["carteira_analitica"])

# Movimentação B3
mov = movimentacao_b3.read_all("movimentacao-2023-01-01-ate-31-12-2023.xlsx")
print(mov["movimentacao"])

Detalhes técnicos

  • Todos os arquivos são lidos com pandas.read_excel usando o engine calamine — uma implementação em Rust, mais rápida e sem dependência do Java (ao contrário do xlrd/openpyxl para .xls antigos).

  • Suporta tanto .xls (formato legado) quanto .xlsx.

  • Por padrão, cada função normaliza nomes de coluna (snake_case) e coage tipos conhecidos (ex.: qtd). Passe raw=True para receber os dados exatamente como estão no Excel, sem nenhuma transformação — veja Normalização de colunas.

  • Todo read_* aceita tanto um caminho (str/Path) quanto um objeto file-like em bytes (BytesIO, UploadedFile do Django, etc.) — útil quando o Excel chega via upload em vez de estar em disco:

    df = carteira_cotizada.read_carteira_analitica(uploaded_file)  # objeto file-like
    

    infer_excel_date() retorna None quando a origem não tem nome de arquivo associado (ex.: BytesIO).

  • A lib publica o marcador py.typed — type checkers (mypy/pyright) do projeto consumidor reconhecem os tipos exportados.


Desenvolvimento

# Clonar e instalar dependências
git clone https://github.com/seu-usuario/etl-ativa-investimentos.git
cd etl-ativa-investimentos
poetry install

# Rodar testes
poetry run pytest -v

Documentação completa

A referência completa da lib — guia rápido, inputs/outputs, normalização de colunas, entidades tipadas, tratamento de erros, formato de dados de cada relatório e referência de API — vive em docs/ como um site mkdocs-material. Para servir localmente:

poetry install --with docs
poetry run mkdocs serve

Abre em http://127.0.0.1:8000. Para gerar o site estático:

poetry run mkdocs build

Atalhos para a documentação de formato de dados (o de-para completo de cada aba):


Licença

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

etl_ativa_investimentos-0.1.6.tar.gz (19.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

etl_ativa_investimentos-0.1.6-py3-none-any.whl (24.4 kB view details)

Uploaded Python 3

File details

Details for the file etl_ativa_investimentos-0.1.6.tar.gz.

File metadata

  • Download URL: etl_ativa_investimentos-0.1.6.tar.gz
  • Upload date:
  • Size: 19.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.4.1 CPython/3.14.4 Linux/6.6.87.2-microsoft-standard-WSL2

File hashes

Hashes for etl_ativa_investimentos-0.1.6.tar.gz
Algorithm Hash digest
SHA256 a3bc38620da1b637e0450ee6a86f0ab0837fe1989aff8745d374591ef4179cea
MD5 4ffb4ac279afc761a13d51c9db30013b
BLAKE2b-256 d0f4f9a813ea27bf57d765cf77c9da8b58dce2b71d665876db6459a3eaead363

See more details on using hashes here.

File details

Details for the file etl_ativa_investimentos-0.1.6-py3-none-any.whl.

File metadata

  • Download URL: etl_ativa_investimentos-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 24.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.4.1 CPython/3.14.4 Linux/6.6.87.2-microsoft-standard-WSL2

File hashes

Hashes for etl_ativa_investimentos-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 39e048a285f2e6ce291ba2a8736fcbcdb1581bf405d421ecf5d9b6e15655cf09
MD5 993637a5784a082616609a6f1f03e6b1
BLAKE2b-256 8249e17a6aea238107f1df85c12711c1ab8b7366efa3ce10ec83b9bf42a99ed2

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.6 This release

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page