Skip to content

About

Otimizador de carteiras de ações, FIIs e fundos com dados da B3, CVM e Yahoo: Sharpe, Sortino, linearidade do excesso, posições vendidas (hedge) e walk-forward (auto-otimização)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Otimizador de Portfólio

Versão Desktop - Manual do Usuário

Documento de referência completo para operação do sistema de

otimização de portfólio com walk-forward e ranking automático de ativos.

Versão 3.0 • 2026


Arquivo único, sem instalação e sem Python: baixe o .exe e dê duplo clique. Detalhes e o que esperar na primeira execução estão na seção 1.3. Para Linux e macOS, rode a partir do código (seção 1.4).


1. Introdução

O Otimizador de Portfólio é uma aplicação desktop desenvolvida em Python com interface PyQt5 (desktop_app_qt.py), apoiada no motor de cálculo optimizer.py. Seu objetivo é auxiliar analistas e gestores a construir carteiras de ativos financeiros de forma quantitativa, combinando técnicas de otimização matemática, análise de risco e validação fora da amostra (out-of-sample).

⚠️ Sobre a versão Tkinter: o projeto nasceu em Tkinter (desktop_app_FULL.py) e esse arquivo continua no repositório por referência histórica, mas não é mais mantido. Ele não possui os recursos introduzidos a partir da versão 2.1 (objetivos Under Water e Sharpe do Excesso, meta absoluta, tabela ordenável, coluna Meta%, degradação graciosa, exportação numérica, entre outros). Use sempre a versão PyQt5.

1.1 Principais Funcionalidades

  • Carregamento de dados históricos de preços via planilha Excel ou busca online em várias fontes (Yahoo Finance, B3/COTAHIST, Excel/STOCKHISTORY e CVM/fundos de investimento).
  • Configuração de janelas temporais separadas para otimização e validação.
  • Oito objetivos de otimização, incluindo Sharpe, Sortino, Under Water, linearidade e dois objetivos aplicados ao excesso sobre a referência.
  • Restrições globais e individuais de peso por ativo, com importação via arquivo Excel/CSV.
  • Meta de retorno opcional em dois modos: relativa à referência ou absoluta (% ao ano).
  • Suporte a posições vendidas (short selling / hedge), inclusive na Auto-Otimização.
  • Sistema de ranking automático de ativos com pesos personalizáveis.
  • Resultados in-sample e out-of-sample comparados lado a lado.
  • Tabelas de retornos mensais com cálculo de excesso sobre a referência.
  • Auto-Otimização com walk-forward sobre múltiplas combinações de parâmetros.
  • Tabela de resultados ordenável por qualquer coluna, com ordenação numérica correta.
  • Solver com multi-start automático e degradação graciosa (entrega a melhor carteira viável em vez de abortar).
  • Exportação para CSV e Excel com valores numéricos de verdade, prontos para cálculo.

1.2 Requisitos do Sistema

Componente Requisito
Sistema Operacional Windows 10/11, Linux ou macOS
Python 3.8 ou superior (recomendado 3.10+)
Bibliotecas PyQt5, pandas, numpy, scipy, matplotlib, openpyxl
Opcional yfinance (Yahoo Finance), requests (B3 e CVM — normalmente já presente), xlwings + Excel 365/Windows (importação via Excel)
Módulo adicional optimizer.py (incluso no projeto)
Resolução de tela Mínimo 1400 × 900 pixels (recomendado 2100+ de largura para ver a tabela da Auto-Otimização inteira)
Formato de dados Planilha Excel (.xlsx ou .xls) e CSV

1.3 Baixar o Executável Pronto (Windows)

Quem só quer usar o programa não precisa instalar Python nem baixar o código:

Na página do release, baixe o arquivo Otimizador de Portfolio.exe (cerca de 112 MB). Ele sozinho é o programa inteiro: não há instalador, não há pasta para descompactar, não há nada mais para instalar. Salve onde preferir e dê duplo clique.

O link acima sempre aponta para a versão mais recente. Link direto para o .exe da versão atual.

Três coisas normais que costumam assustar na primeira vez:

O que acontece Por quê
O Windows mostra "O Windows protegeu o seu computador" e não abre O executável não é assinado digitalmente (a assinatura é um certificado pago). Clique em Mais informações → Executar assim mesmo.
Demora alguns segundos para a janela aparecer É um executável de arquivo único: ele descompacta o próprio conteúdo a cada execução. Acontece sempre, não só na primeira vez.
Abre uma janela preta de console junto com o programa É proposital: ali sai o andamento da auto-otimização, a composição das carteiras e os avisos do solver. Se algo der errado, é essa janela que diz o quê. Não feche — fechá-la encerra o programa.

⚠️ Alguns antivírus desconfiam de executáveis gerados pelo PyInstaller, mesmo sem haver nada de errado com eles. Se o seu bloquear o arquivo, será preciso liberá-lo manualmente — ou usar o programa pelo código-fonte (seção 1.4).

💡 Windows apenas. No Linux e no macOS, rode a partir do código-fonte, como descrito a seguir. O programa funciona nos três sistemas; só o executável pronto é específico do Windows.

1.4 Como Iniciar o Programa (a partir do código)

  • Abra o terminal (Prompt de Comando ou PowerShell no Windows).
  • Navegue até a pasta onde os arquivos do projeto estão localizados.
  • Execute: python desktop_app_qt.py
  • A janela principal do programa será exibida.

💡 O arquivo optimizer.py precisa estar na mesma pasta que desktop_app_qt.py para o programa funcionar corretamente.

⚠️ Os módulos das fontes de dados (cvm_fundos.py, b3_series_wide_com_limpeza.py, b3_excel_rendafixa.py, eventos_corporativos.py, tabela_fii_cnpj.py) também precisam estar na mesma pasta. Sem eles o aplicativo abre normalmente, mas o botão (ou a opção) correspondente avisa o que está faltando.

1.5 Gerar o Executável (Windows)

Esta seção é para quem quer construir o executável a partir do código — por exemplo, depois de alterar alguma coisa. Para apenas usar o programa, baixe o executável pronto (seção 1.3).

Para distribuir o programa a quem não tem Python instalado, dê duplo clique em Construir executavel.bat. Ele cuida de tudo: localiza o Python, cria um ambiente isolado (.venv), instala as dependências e chama o PyInstaller.

O resultado é um único arquivo: dist\Otimizador de Portfolio.exe. Ele sozinho já é o programa — basta enviá-lo ao usuário final, que não precisa de Python nem de mais nada instalado.

Duas escolhas feitas na receita de construção (desktop_app_qt.spec), e o porquê:

Escolha Motivo
Arquivo único Simples de distribuir e impossível de errar na hora de abrir. O custo é a velocidade: o executável descompacta o próprio conteúdo a cada execução, então sempre leva alguns segundos para iniciar.
Console ligado O programa imprime o andamento da auto-otimização (steps, composição da carteira, avisos do solver). Escondendo o console esses logs se perdem. Para preferir a janela limpa, troque console=True por False no .spec.

💡 Se um dia a velocidade de abertura pesar mais que a facilidade de distribuir, dá para gerar em pasta (abre bem mais rápido, porque não há descompactação). O .spec traz, ao final, o bloco comentado e as instruções para essa troca.

💡 As fontes opcionais (yfinance e xlwings) são instaladas em separado pelo .bat, sem interromper a construção se alguma falhar — o aplicativo funciona sem elas.

2. Estrutura da Interface

A interface é organizada em 8 abas (tabs) na parte superior da janela. O fluxo de trabalho recomendado segue a ordem das abas da esquerda para a direita.

Aba Função
📁 Dados Carregar planilha Excel, configurar janelas temporais e selecionar ativos
⚙️ Configuração Definir objetivo de otimização, limites de peso, taxa de referência e meta de retorno
🔧 Avançado Configurar restrições individuais de peso por ativo
🔄 Short/Hedge Definir posições vendidas com pesos negativos
🏆 Ranking Calcular e aplicar ranking automático de ativos
📈 Resultados Visualizar métricas in-sample, out-of-sample e composição do portfólio
📅 Retornos Mensais Tabela de retornos mês a mês e excesso sobre a referência
🤖 Auto-Otimização Walk-forward sobre múltiplas combinações de parâmetros automaticamente

3. Aba Dados - Carregamento e Configuração

Esta é a primeira aba a ser utilizada. Todo o fluxo começa aqui: carregue a planilha, configure as datas e selecione os ativos antes de avançar para as demais abas.

3.1 Formato da Planilha Excel

A planilha deve seguir o seguinte padrão:

  • Primeira coluna: datas no formato DD/MM/AAAA (a coluna pode ter qualquer nome; o sistema a renomeia automaticamente para 'Data').
  • Segunda coluna (opcional): taxa de referência ou benchmark (CDI, SELIC, IBOV etc.). O sistema detecta automaticamente se o nome da coluna contiver as palavras: taxa, livre, risco, ibov, ref, cdi ou selic.
  • Demais colunas: séries de preços dos ativos, uma por coluna, com o nome do ativo no cabeçalho.

💡 Os dados devem ser preços (cotas), não retornos. O sistema calcula os retornos internamente via transformação para base zero.

3.2 Carregar Arquivo

  • Clique no botão 📂 Carregar Planilha Excel.
  • Selecione o arquivo .xlsx ou .xls no diálogo que aparecer.
  • O painel 'Informações do Arquivo' exibirá: nome do arquivo, número de linhas e colunas, período disponível (data início e data fim) e total de dias.
  • Se uma taxa de referência for detectada automaticamente, ela aparecerá em verde no painel 'Taxa de Referência Detectada'. Caso contrário, um aviso em vermelho indicará que nenhuma taxa foi encontrada.
  • Acertou ou errou, a escolha não é definitiva: o botão 🏛️ Alterar Ativo de Referência troca a referência a qualquer momento (seção 3.2.3).

⚠️ Se a taxa de referência for detectada automaticamente, o campo de taxa manual na aba Configuração é desabilitado. Se não for detectada, o campo manual permanece disponível para entrada manual do valor acumulado no período.

3.2.1 Fontes Online (Yahoo, B3, Excel e CVM)

Além de carregar uma planilha, o programa busca cotações direto da internet por quatro fontes. Qualquer uma delas alimenta o programa exatamente como uma planilha carregada — mesmo fluxo daí em diante (detecção da taxa de referência, lista de ativos e janelas temporais). Todas entregam séries de preços (ou cotas, no caso dos fundos), e a transformação para base zero é feita internamente ao processar o período.

Fonte Botão Melhor para Requisito
Yahoo Finance 🌐 Importar do Yahoo Finance Ações internacionais, cripto, uso rápido yfinance
B3 (COTAHIST) 🇧🇷 Importar da B3 (COTAHIST) Ações e ETFs brasileiros (fonte oficial) requests
Excel (STOCKHISTORY) 📊 Importar via Excel (renda fixa) ETFs de renda fixa que o COTAHIST não cobre Windows + Excel 365 + xlwings
CVM (fundos) 🏦 Importar Fundos (CVM) Cotas diárias de fundos de investimento requests

💡 As fontes da B3, do Excel e da CVM usam dados oficiais/institucionais, mais confiáveis que o Yahoo para o mercado brasileiro.

Regras de limpeza (iguais nas quatro fontes)

Toda importação online passa pelas mesmas três regras, aplicadas nesta ordem sobre a matriz Data × Ativos:

Ordem Regra
0 Valor zero conta como "sem dado".
1 Coluna sem dado na primeira data → o ativo é excluído.
2 Coluna com mais de k registros consecutivos sem dado → excluída.
3 Lacunas restantes → preenchidas com o valor do dia anterior.

O valor de k é o campo 🧹 Elimina após N dias sem dado (padrão 10), presente nas três janelas de importação junto com o tipo de preço e o período.

⚠️ A ordem importa: as regras 1 e 2 avaliam os buracos antes do preenchimento; a regra 3 vem por último. Se o preenchimento viesse antes, não sobrariam buracos para as regras 1 e 2 analisarem.

💡 Por que isso importa: sem a regra 3, lacunas chegariam como vazio ao otimizador, que descarta a linha inteira quando qualquer ativo falta — ou seja, um único ativo com falha eliminaria aquela data para todos os demais. As exclusões efetuadas pelas regras 1 e 2 são informadas na mensagem ao final da importação.

Importar do Yahoo Finance

Baixe cotações pelo botão 🌐 Importar do Yahoo Finance. Na janela que abre:

  • 📝 Símbolos dos Ativos: um código por linha (ex.: PETR4, VALE3, ITUB4). Mínimo de 2.
  • 💰 Preço e 🧹 Elimina após N dias sem dado: iguais aos das outras fontes (ver regras de limpeza acima).
  • 🏷️ Tipo de ativo: define o sufixo acrescentado automaticamente ao código.
Tipo Comportamento
Ações Brasileiras (.SA) Acrescenta .SA (ex.: PETR4 → PETR4.SA).
Ações Americanas / ETFs / Criptomoedas Usa o código como digitado (ex.: MSFT, BTC-USD).
Códigos Livres do Yahoo Nenhum sufixo é acrescentado — digite exatamente como aparece no Yahoo.
  • 🏛️ Ativo de Referência: informe um benchmark (padrão BOVA11) e marque Incluir. Ele é baixado junto e vira a coluna de referência, renomeada para Taxa_Ref_<CÓDIGO> e posicionada como segunda coluna — é isso que faz a detecção automática reconhecê-la e habilitar os objetivos de excesso. Sugestões: BOVA11 (Ibovespa), LFTS11 (CDI), SMAL11 (Small Caps), IVV (S&P 500).
  • 📅 Período: datas de início e fim da busca (padrão: últimos 3 anos).

Clique em 🚀 Buscar e Importar. Uma barra de progresso mostra o andamento ativo a ativo.

💡 Códigos que já contenham ponto (ex.: PETR4.SA) são usados como digitados, mesmo no modo com sufixo — não vira PETR4.SA.SA.

⚠️ Séries com menos de 6 pregões no período são descartadas já na busca, e os símbolos sem dados são listados ao final; o que sobrar ainda passa pelas três regras de limpeza. Se o ativo de referência não sobreviver (não retornou ou foi excluído na limpeza), a importação continua sem ele e o programa avisa — nesse caso os objetivos que dependem da referência ficam indisponíveis.

⚠️ Requer a biblioteca yfinance (pip install yfinance). Sem ela o aplicativo funciona normalmente, apenas esse botão exibe um aviso explicando como instalar.

💡 Os dados vêm como preços de fechamento, exatamente o formato que o programa espera — a transformação para base zero continua sendo feita internamente ao processar o período.

Importar da B3 (COTAHIST) — fontes nacionais

O botão 🇧🇷 Importar da B3 (COTAHIST) baixa os arquivos anuais oficiais da B3 (mercado à vista) e monta a série de preços dos ativos pedidos. Por ser a fonte oficial da bolsa brasileira, é mais confiável que o Yahoo para ações e ETFs negociados na B3.

A janela é parecida com a do Yahoo, com alguns campos próprios:

  • 📝 Símbolos: os códigos exatamente como negociados na B3 (ex.: PETR4, VALE3, BOVA11).
  • 💰 Preço: Abertura, Máximo, Mínimo ou Fechamento (padrão).
  • 🧹 Elimina após N dias sem dado: regra de limpeza (padrão 10). Se um ativo ficar mais de N pregões seguidos sem cotação, é descartado; lacunas menores são preenchidas com o preço do dia anterior. Ativos sem cotação na primeira data também são descartados.
  • 🏛️ Ativo de Referência e 📅 Período: iguais aos do Yahoo.

⚠️ O primeiro download de cada ano é grande (dezenas de MB) e pode levar de segundos a minutos — a janela pode parecer parada enquanto baixa cada ano. A barra de progresso avança a cada ano concluído.

⚠️ Requer a biblioteca requests (normalmente já instalada). Cobre bem ações e a maioria dos ETFs; para ETFs de renda fixa que a B3 não cobre bem, use a fonte via Excel abaixo.

🧮 Ajuste por eventos corporativos (opcional)

O COTAHIST traz os preços como foram negociados. Num desdobramento de 1 para 4 o preço cai a um quarto de um dia para o outro; num dividendo, cai o valor pago. Para o otimizador, as duas coisas parecem perdas — e não são. Na janela da B3, o quadro 🧮 Ajuste por eventos corporativos corrige isso:

  • Ajustar desdobramentos, grupamentos e bonificações — tira da série os saltos falsos (retorno de preço).
  • Ajustar também os proventos (dividendos, JCP, rendimentos de FII) — soma ao retorno o que foi pago, como se fosse reinvestido no próprio papel (retorno total). Só fica disponível com a primeira marcada.

Desmarcado (o padrão de fábrica), a importação é exatamente a de sempre. A escolha fica gravada para as próximas vezes.

Como o ajuste é feito. Para cada evento com data-com D, todos os preços até D (inclusive) são multiplicados por um fator; os preços depois de D não mudam — o último preço da série continua sendo o real. No desdobramento de 1 para 4 o fator é 0,25; num dividendo de 2% do preço, 0,98.

De onde vêm os eventos:

Evento Fonte
Desdobramentos, grupamentos e bonificações Lista oficial da B3 (desde os anos 90)
Desdobramentos que faltam na lista da B3 O próprio COTAHIST (ver abaixo)
Dividendos, JCP, restituições de capital (ações) Histórico de proventos da B3 (desde 1996), já com o percentual sobre o preço da data-com
Rendimentos e amortizações de FIIs, Fiagro e FIDC listados Fundos.NET (avisos publicados pelos próprios fundos) + B3 (últimos ~12 meses)
Rendimentos de FI-Infra e FIP B3 (últimos ~12 meses); o histórico anterior, só com a opção de site não oficial — ver abaixo
Ações antigas cotadas por lote de mil Campo FATCOT do COTAHIST: tudo vira preço por ação

Desdobramentos ausentes na lista da B3. Acontece (os da Magazine Luiza em 2017 e 2019 não estão lá). O programa os encontra no COTAHIST quando três marcas aparecem no mesmo pregão: o número de distribuição muda (a B3 o muda exatamente no dia "ex"), a cotação salta x vezes (x = 2, 3, 4, 8, 10...) e a quantidade negociada passa a ser cerca de x vezes a de antes. Um tombo de mercado derruba o preço mas não multiplica a quantidade, e por isso não é confundido com desdobramento.

O relatório. Ao final da importação abre-se uma janela com tudo o que foi ajustado, papel por papel: cada evento com data-com, descrição, fator e fonte, e o retorno do período sem e com ajuste. Dá para copiar ou salvar como .txt. Ela também mostra os avisos — por exemplo, um salto grande que não pôde ser explicado por nenhum evento ("confira se há evento faltando"). Se a B3 não responder para algum papel, ele fica SEM ajuste e aparece em destaque — nunca é ajustado pela metade em silêncio.

Tempo de download. São consultas pequenas, feitas várias ao mesmo tempo: alguns segundos por papel na primeira vez. Para FIIs, é um aviso do Fundos.NET por mês do período (cerca de 36 em três anos), e o Fundos.NET costuma ser o mais lento. Durante a espera, a linha de andamento da janela mostra o que ainda está pendente (ex.: "aguardando HGLG11 12/37 avisos"), e o console registra o tempo de cada FII e as respostas lentas ou repetidas. Tudo fica guardado na pasta cache_eventos, dentro da pasta dos dados de eventos, e nas buscas seguintes só se baixa o que for novo — repetir a mesma importação no mesmo dia não consulta nada. São arquivos pequenos e não são apagados ao fechar.

Pasta dos dados de eventos. O campo "📁 Pasta dos dados de eventos" (com Procurar...), no quadro do ajuste, define onde ficam o cache_eventos e o fii_cnpj.csv. O padrão é a pasta de dados do programa: a pasta do .py, ou %APPDATA%\OtimizadorPortfolio no executável. A escolha fica gravada; se a pasta deixar de existir (pendrive removido, por exemplo), o programa volta ao padrão. Apontar o .py e o .exe para a mesma pasta faz os dois compartilharem o cache e os CNPJs descobertos. Com o ajuste desmarcado, o campo fica desabilitado e a pasta não é usada.

FIIs, Fiagro e a tabela de CNPJs — mantida pelo próprio programa. A B3 só guarda os rendimentos de FII dos últimos ~12 meses; os anteriores vêm do Fundos.NET, que é organizado por CNPJ do fundo. O programa já traz uma tabela com cerca de 440 FIIs (tabela_fii_cnpj.py). Quando aparece um FII que não está nela, o programa:

  1. procura, na lista de avisos de rendimento recentes de todos os FIIs no Fundos.NET, os do fundo com o mesmo nome de pregão da B3;
  2. baixa um desses avisos e confere que ele cita o código (ou o ISIN) do papel — um nome parecido nunca basta;
  3. usa o CNPJ do aviso e o guarda no arquivo fii_cnpj.csv, na pasta dos dados de eventos. Nas importações seguintes ele já está lá.

O relatório mostra quando isso acontece ("ℹ️ FII fora da tabela: CNPJ ... encontrado no Fundos.NET e conferido"). Se o fundo não for achado (por exemplo, não distribuiu rendimentos nos últimos 5 meses), o relatório avisa que só os últimos 12 meses foram ajustados, e o programa tenta de novo depois de 30 dias. Por que não a CVM ou sites de terceiros: o cadastro de FII da CVM tem o código de negociação mal preenchido, e sites como o Clube FII podem mudar ou bloquear o acesso sem aviso; o Fundos.NET é a fonte oficial e é de onde o histórico vem de qualquer forma.

Também é possível incluir um fundo à mão no mesmo fii_cnpj.csv (uma linha por fundo; ele tem prioridade sobre a tabela):

codigo;cnpj
HGLG11;11728688000147

Site não oficial (opcional, desligado de fábrica). As fontes oficiais não têm o histórico de rendimentos de FI-Infra e FIP: a B3 guarda só ~12 meses e esses fundos não publicam no Fundos.NET. Para completar, a caixa "Completar com site não oficial quando a fonte oficial não tiver o histórico" (que só aparece com os proventos marcados) busca os proventos num site de terceiros. O padrão são dois endereços, tentados nesta ordem: o Carteira Falcão (https://carteirafalcao.com.br/dividendos/) e o BRFiis (https://brfiis.com.br/fundos/). O código do papel é acrescentado no fim de cada um, ou entra no lugar de {ticker}; os endereços são separados por ;. O segundo só é consultado quando o primeiro não passa na conferência ou não cobre o período — o caso do XPIE11, cujas amortizações o Carteira Falcão não traz e o BRFiis traz. Outro site serve se mostrar uma tabela com as colunas "Data com" (ou "Data base") e "Valor".

Regras, para que um site de terceiros não contamine o ajuste:

  • Só tapa buracos: é consultado apenas para os papéis que ficariam com os ~12 meses da B3. Ações, units, FIIs e Fiagro continuam só com as fontes oficiais.
  • Conferência obrigatória: os últimos 12 meses do site precisam bater com os da B3 — data e valor, com tolerância de 1 centavo pelo arredondamento — em pelo menos 90% das datas. Se o site chamar de "data com" a data ex (o Carteira Falcão faz isso), a conferência percebe e corrige. Se não bater (o XPIE11 no Carteira Falcão não traz as amortizações, por exemplo), o site é ignorado para aquele papel, o próximo da lista é tentado e o relatório diz por quê.
  • Fonte visível: no relatório, esses proventos aparecem como [site: carteirafalcao.com.br] (ou [site: brfiis.com.br]), com uma nota "FONTE NÃO OFICIAL" e o resultado da conferência.
  • Respeito ao site: o programa lê o robots.txt antes e não consulta páginas que ele proíba; lê a página do papel e, se a tabela for paginada (o BRFiis mostra 6 linhas por página), as seguintes com 1 s de pausa entre elas, só até alcançar o início do período; tudo fica guardado no cache.
  • Termos de uso: os termos do Carteira Falcão permitem usar os dados para fins pessoais; os do BRFiis não restringem o uso dos dados. Cabe a quem usa respeitar os termos do site escolhido. Não foram incluídos: o Radar FII e o Status Invest (os termos proíbem copiar os dados ou montar base com eles) e o Funds Explorer (a tabela é montada por JavaScript no navegador; a página não traz os dados).

Limites conhecidos:

  • Direitos de subscrição não são ajustados (dependem de cada investidor exercer ou não).
  • Cisões (quando o acionista recebe ações de outra empresa, como a Getnet saindo do Santander em 2021) não são ajustadas: a queda do dia "ex" fica na série, e o relatório avisa com a data.
  • Units (TAEE11, KLBN11, SANB11, BPAC11...) usam os eventos e proventos que a B3 registra para a própria unit — não os das ações que a compõem, que podem ter sido diferentes (em 2014 o Santander agrupou as ações, mas o preço da unit não mudou).
  • Proventos repetidos na mesma data-com (ex.: três linhas iguais da Klabin em dez/2025) são tratados como parcelas e somados: é assim que a B3 registra um provento pago em várias vezes.
  • O JCP entra pelo valor bruto — como fazem a B3, o Yahoo e o Excel.
  • Bonificações pequenas (ex.: 5%) que faltem na lista da B3 não são detectadas pelo COTAHIST: um salto de 5% não se distingue de um pregão comum.
  • ETFs e BDRs: os desdobramentos são tratados; proventos, quando a B3 os tiver.
  • FI-Infra (KDIF11, BDIF11, CDII11, JURO11, IFRA11...) e FIP (XPIE11...): pelas fontes oficiais, só os rendimentos dos últimos ~12 meses são ajustados, e o relatório avisa (o histórico anterior só com a opção de site não oficial, acima). Esses fundos não publicam o aviso estruturado no Fundos.NET, e a B3 só guarda 12 meses. Foram investigados: (1) a página de eventos de fundos da B3 — usa a mesma consulta, 12 meses; (2) o informe diário da CVM — com o CNPJ certo, a queda da cota na data-com reproduz o rendimento com erro de ~0,1 ponto (CDII11 e JURO11), mas é uma estimativa, o CNPJ não pode ser descoberto automaticamente com segurança (muitos FI-Infra pagam ~1% no fim de cada mês) e o FIP não informa cota diária; (3) sites de terceiros — descartados por não serem fonte oficial. Fica em aberto até haver uma fonte definitiva.
  • Se a B3 não responder para um FII ou Fiagro cujo CNPJ é conhecido, ele ainda recebe os rendimentos do Fundos.NET (os desdobramentos ficam só com a detecção pelo COTAHIST), e o relatório avisa.

Comparação com o Excel (STOCKHISTORY). O Excel ajusta corretamente desdobramentos, grupamentos e bonificações, mas só ajusta proventos de 2024 em diante (e ainda deixa passar alguns). De 2020 a 2026, isso deixa de fora cerca de 48 pontos percentuais do retorno de BBAS3 e de VIVT3. Com os proventos marcados, a importação da B3 dá o retorno total completo; nos desdobramentos, o resultado coincide com o do Excel.

💡 Para conferir a conexão com a B3 fora do programa: python eventos_corporativos.py PETR4 HGLG11 lista os eventos que a B3 devolve para esses papéis. Com --descobrir, os FIIs têm o CNPJ procurado no Fundos.NET como se não estivessem na tabela.

Importar via Excel (renda fixa) — fonte complementar

O botão 📊 Importar via Excel (renda fixa) usa a função STOCKHISTORY do Excel (dados LSEG/Refinitiv) para buscar os ETFs de renda fixa que o COTAHIST não cobre bem (ex.: FIXA11, IMAB11, B5P211, IRFM11). Os campos são os mesmos da importação da B3.

⚠️ Requisitos específicos: Windows com Excel 365 instalado e logado, e a biblioteca xlwings (pip install xlwings). É a única fonte que não roda em Linux/macOS. Sem esses requisitos, o botão abre normalmente mas a busca informa o que está faltando.

💡 Fonte complementar, não substituta: use a B3 como fonte principal e o Excel só para os códigos de renda fixa que faltarem. Não misture as duas fontes na mesma carteira — os preços têm origens diferentes (B3 vs LSEG).

Importar Fundos da CVM

O botão 🏦 Importar Fundos (CVM) traz as cotas diárias de fundos de investimento a partir dos dados abertos da CVM. Permite otimizar carteiras de fundos exatamente como se faz com ações — a cota é o "preço" do fundo.

Na janela:

  • 📝 CNPJs dos Fundos: um CNPJ por linha, com ou sem pontuação (29.152.383/0001-03 ou 29152383000103). Mínimo de 2.
  • 📁 Pasta de cache: onde os arquivos baixados ficam guardados. Se existir um CNPJ.csv nessa pasta, os CNPJs são carregados dele automaticamente.
  • 🧹 Elimina após N dias sem dado e 📅 Período: iguais às outras fontes.
  • 🏛️ Ativo de Referência: diferente das demais — como o nome do fundo só é conhecido depois da busca, ao final aparece a lista dos fundos obtidos para você escolher qual será a referência. Um fundo referenciado DI costuma ser a melhor escolha.

O que é baixado automaticamente:

Arquivo Origem
Cadastro (nomes dos fundos) .../FI/CAD/DADOS/cad_fi_hist.zip
Informe diário, 2021 em diante .../FI/DOC/INF_DIARIO/DADOS/inf_diario_fi_AAAAMM.zip (mensal)
Informe diário, antes de 2021 .../FI/DOC/INF_DIARIO/DADOS/HIST/inf_diario_fi_AAAA.zip (anual)

⚠️ Os arquivos são grandes — cada informe diário traz todos os fundos do país. A primeira busca de um período baixa e guarda em cache; as buscas seguintes reaproveitam o que já está lá. Um zip anual do histórico traz os 12 meses de uma vez, então basta um download por ano antigo.

O cache: apagar ao sair, ou guardar?

Os dois lados têm razão, e por isso quem decide é você. Na janela de importação, logo abaixo da pasta, existe a caixa ☑️ Apagar os arquivos baixados ao fechar o programa:

Caixa O que acontece Para quem
Marcada (padrão) Ao fechar, os arquivos baixados são apagados. Repetir a busca depois baixa tudo de novo. Quem usa de vez em quando e não quer centenas de megabytes parados no disco.
Desmarcada Os arquivos ficam guardados e são reaproveitados nas próximas aberturas. A pasta cresce com o tempo. Quem acompanha sempre os mesmos fundos e repete as buscas — economiza um download grande a cada vez.

A escolha fica gravada e vale para as próximas aberturas; você só precisa decidir uma vez. Ela é guardada num preferencias.json ao lado do cache (um arquivo minúsculo, de texto).

A limpeza, quando acontece, é seletiva: só saem os arquivos com cara de download da CVM (inf_diario_fi_*.csv e cad_fi_hist*.csv). Qualquer outro arquivo seu que esteja na pasta — o CNPJ.csv, por exemplo — não é tocado. A pasta em si só é removida se ficar vazia.

Como você executa Pasta padrão do cache
Script (python desktop_app_qt.py) <pasta do projeto>\cvm_cache
Executável (.exe) %APPDATA%\OtimizadorPortfolio\cvm_cache

A pasta é exibida (e pode ser trocada) na própria janela de importação. A que você escolher é lembrada e volta nas próximas aberturas — é só apontar uma vez. Se a pasta lembrada desaparecer (pendrive removido, pasta apagada) e não puder ser recriada, o programa volta ao padrão em vez de insistir num caminho morto.

💡 A pasta é criada assim que a janela de importação abre, mesmo antes da primeira busca. É isso que permite chegar nela pelo Procurar... e deixar ali o seu CNPJ.csv. No executável isso importa mais ainda, porque %APPDATA%\OtimizadorPortfolio não existe numa instalação nova.

💡 Seja qual for a escolha, a base já importada pode ser salva a qualquer momento com 💾 Baixar Base de Dados Carregada (seção 3.2.2) — um arquivo pequeno, que recarrega pelo botão de planilha e dispensa voltar à CVM.

⚠️ Por que o executável usa %APPDATA% e não a própria pasta: um executável único extrai seu conteúdo para uma pasta temporária e a apaga ao fechar. Se o cache ficasse ali, guardá-lo não adiantaria nada — seria apagado de todo jeito. Em %APPDATA% ele persiste, e sobrevive inclusive à troca do .exe por uma versão nova.

💡 As colunas recebem o nome do fundo (denominação social vigente no cadastro), que costuma ser longo. É esse nome que aparece na lista de ativos, na composição da carteira e nos gráficos.

💡 O formato dos CSVs da CVM muda conforme o ano (nome da coluna de CNPJ, codificação, data em DD/MM/AAAA ou AAAA-MM-DD, decimal com vírgula ou ponto). Tudo isso é tratado automaticamente, e a comparação de CNPJ ignora a pontuação.

3.2.2 Baixar a Base Carregada

O botão 💾 Baixar Base de Dados Carregada salva em disco a base bruta atualmente em memória — não importa a origem (planilha, Yahoo, B3, Excel ou CVM). Útil para conferir os dados, ajustá-los à mão ou guardar uma cópia da série que você montou online.

  • Fica desabilitado enquanto nenhuma base estiver carregada; habilita automaticamente após carregar/importar.
  • Escolha .xlsx (Excel, com datas em DD/MM/AAAA, preços numéricos, cabeçalho em negrito e primeira linha congelada) ou .csv (separador ; e decimal ,, padrão que o Excel pt-BR abre direto).
  • Grava exatamente Data | (Taxa_Ref, se houver) | ativos..., sem a transformação para base zero — ou seja, os preços originais, do jeito que o otimizador os recebe.

💡 Os preços são gravados com precisão total (sem arredondamento), para que o arquivo seja fiel ao dado usado nos cálculos. No Excel, a exibição fica limpa (2 casas) mas o valor exato é preservado na célula.

💡 Um bom uso: importe online (Yahoo/B3/Excel), baixe a base, ajuste o que precisar numa planilha e recarregue pelo botão 📂 Carregar Planilha Excel.

3.2.3 Alterar o Ativo de Referência

O botão 🏛️ Alterar Ativo de Referência troca a referência sem reimportar nada. Serve para duas situações comuns:

  • A detecção automática escolheu a coluna errada — ou não escolheu nenhuma.
  • Você quer comparar a mesma carteira contra benchmarks diferentes (CDI, Ibovespa, um fundo específico) sem baixar tudo de novo.

Como funciona:

  1. Abre a lista de todas as colunas da base, com a referência atual já marcada.
  2. A referência antiga volta a ser um ativo comum, recuperando o nome original (o prefixo Taxa_Ref_ só é retirado quando foi o programa que o colocou; nomes que vieram da sua planilha são preservados como estão).
  3. A nova referência é renomeada para Taxa_Ref_<NOME> e movida para a segunda coluna.
  4. A lista de ativos, o painel Taxa de Referência Detectada e os objetivos de excesso são atualizados na hora.

Também existe a opção Seguir sem referência: a base fica só com ativos e os objetivos que dependem da referência somem da aba Configuração. Se algum deles estava selecionado, o programa volta sozinho para Maximizar Sharpe Ratio — assim não há como rodar uma otimização de excesso sem ter contra o que comparar.

⚠️ Processe o período novamente depois de trocar. A troca mexe na base bruta; os cálculos já feitos continuam valendo para a referência antiga até você clicar em ⚡ Processar Período Selecionado. O programa avisa isso na própria mensagem de confirmação.

💡 Por que isso é necessário e não basta a detecção automática: ela procura palavras como taxa, livre, risco, ibov, ref, cdi e selic no nome da segunda coluna. Entre fundos, "ref" aparece em qualquer REFERENCIADO DI — e um palpite errado é pior do que nenhum. Com a troca manual, o palpite deixa de ser definitivo.

⚠️ A decisão agora é da interface, não do otimizador. Antes, o otimizador refazia o mesmo palpite por conta própria a cada cálculo. Se a segunda coluna fosse um fundo REFERENCIADO DI que você quisesse como ativo, ele era engolido como taxa de referência e sumia da carteira — ou a otimização parava com um erro de coluna ausente. Hoje a interface informa explicitamente qual é a referência (ou que não há nenhuma), e o palpite só é usado por quem chama o otimizador direto, fora do programa.

3.3 Configurar Janelas Temporais

Após carregar o arquivo, configure as três datas críticas que definem os dois períodos de análise:

Data Descrição
📊 Início da Otimização Data inicial dos dados usados para calibrar o portfólio.
🎯 Fim da Otimização Data final da janela de treinamento (in-sample).
📈 Fim da Análise Data final do período de validação (out-of-sample). Só ativo se 'Usar validação' estiver marcado.

Ao carregar o arquivo, o sistema preenche automaticamente as datas sugeridas usando a proporção de 70% para otimização e 30% para validação. Você pode ajustar livremente clicando nos campos de data.

O painel abaixo das datas exibe em tempo real a quantidade de dias de cada janela e o percentual que representam do período total.

💡 O checkbox '✅ Usar validação (forward test)' permite desabilitar a janela de validação. Nesse caso, o programa usará apenas o período de otimização em todas as análises.

  • Após ajustar as datas, clique em ⚡ Processar Período Selecionado.
  • O sistema filtrará os dados brutos para os períodos configurados e aplicará a transformação para base zero.
  • Uma mensagem de sucesso confirmará quantos dias e ativos estão disponíveis. Ativos com valor zero ou ausente no primeiro dia do período são automaticamente removidos.

3.4 Seleção de Ativos

O painel direito exibe a lista de todos os ativos disponíveis na planilha (excluindo a coluna de data e a taxa de referência, se detectada).

  • Seleção simples: clique em um ativo.
  • Seleção múltipla: Ctrl + clique para adicionar ativos à seleção.
  • Intervalo: Shift + clique para selecionar um intervalo contínuo.
  • ✅ Todos: seleciona todos os ativos de uma vez.
  • ❌ Limpar: remove toda a seleção.

⚠️ É necessário selecionar no mínimo 2 ativos para executar a otimização.

O contador no rodapé do painel mostra quantos ativos estão selecionados em relação ao total disponível (ex.: 'Selecionados: 8/25').

4. Aba Configuração - Parâmetros de Otimização

Nesta aba você define como o algoritmo deve buscar o portfólio ótimo: qual métrica maximizar (ou minimizar), os limites de participação de cada ativo e a taxa de referência utilizada nos cálculos de excesso de retorno.

4.1 Objetivo de Otimização

Selecione um dos objetivos disponíveis pelo botão de rádio:

Objetivo Descrição
Maximizar Sharpe Ratio Maximiza o retorno excedente à taxa de referência por unidade de risco: (retorno anualizado − referência anualizada) ÷ volatilidade anualizada — o mesmo Sharpe exibido na aba Resultados. Objetivo mais comum para carteiras balanceadas.
Maximizar Sortino Ratio Semelhante ao Sharpe, mas penaliza apenas a volatilidade de queda (downside). Não pune oscilações de alta — útil quando a preocupação é o risco de perda.
Minimizar Risco Minimiza a volatilidade do portfólio independentemente do retorno. Ideal para perfis conservadores.
Minimizar Under Water Minimiza o total de perdas acumuladas do período — a soma de todos os retornos diários negativos. É uma medida de risco assimétrica: pune apenas queda, nunca oscilação de alta (ao contrário da volatilidade). Combina especialmente bem com a Meta de Retorno.
Maximizar Sharpe/(1-R²) Sharpe anualizado dividido por (1 − R²) da curva acumulada — a "Sharp / (1 - Rquad)" da planilha original. Premia risco-retorno e linearidade. Substituiu o antigo Inclinação/[(1-R²)×Vol], que em algumas bases não convergia.
Maximizar Qualidade da Linearidade Maximiza o R² da regressão do retorno acumulado. Prioriza ativos com comportamento linear e previsível. Não depende da taxa de referência.

Objetivos com Taxa de Referência

Os dois objetivos abaixo aparecem em uma seção separada e só ficam disponíveis quando há taxa de referência e não há posição vendida (ver 6.3). Ambos trabalham sobre a curva do excesso (carteira − referência):

Objetivo Descrição
Maximizar Linearidade do Excesso Maximiza inclinação_excesso ÷ [(1 − R²_excesso) × vol_excesso]. Premia uma curva de excesso reta (R² alto), ou seja, uma vantagem sobre a referência que cresce de forma regular.
Maximizar Sharpe do Excesso É a Linearidade do Excesso sem o fator (1 − R²): maximiza inclinação_excesso ÷ vol_excesso. Premia o risco-retorno do excesso sem exigir linearidade.

💡 O objetivo "Maximizar Inclinação" (isolado) foi removido na versão 3.0 por não apresentar vantagem prática sobre os demais critérios. O cálculo de inclinação usado na aba Ranking é independente e continua funcionando normalmente.

4.2 Limites de Peso Globais

Defina os limites de participação de cada ativo no portfólio usando os controles deslizantes:

  • Peso mínimo por ativo (%): participação mínima que qualquer ativo selecionado deve ter. Valores típicos: 0% a 5%. Use 0% para permitir que o otimizador exclua ativos.
  • Peso máximo por ativo (%): participação máxima de qualquer ativo. Limita a concentração. Valores típicos: 15% a 30%.

💡 Os pesos são sempre positivos e somam 100% para posições long. Se houver posições short configuradas, os pesos dos ativos long ainda somam 100% antes do ajuste pelas posições vendidas.

4.3 Taxa de Referência

A taxa de referência é usada para calcular o Sharpe Ratio e o excesso de retorno.

  • Detecção automática: se a planilha contiver uma coluna de benchmark, o campo de taxa manual é desabilitado e a taxa é extraída automaticamente dos dados.
  • Taxa manual: quando não houver coluna de benchmark, informe o valor acumulado no período de otimização (ex.: para 12% ao ano em um período de 2 anos, informe 25.44, que corresponde a (1,12)² − 1 ≈ 25,44%).

4.4 Meta de Retorno (Opcional)

A meta de retorno permite exigir um retorno mínimo do portfólio, combinando essa exigência com o objetivo escolhido acima. Na prática, o otimizador busca atingir a meta com o menor risco possível — o ponto ideal entre "maximizar retorno" e "minimizar risco".

Marque 'Exigir meta de retorno mínima' e escolha um dos dois modos:

Modo Como o alvo é calculado Quando usar
Relativa Referência × (1 + Meta ÷ 100) no período. Ex.: referência 12% e meta 5% → alvo 12,6%. Quando o que importa é bater a referência por uma margem ("quero 30% acima do CDI"). Acompanha automaticamente a referência de cada step.
Absoluta (1 + Meta ÷ 100)^(pregões ÷ 252) − 1. Ex.: 15% ao ano em 126 pregões → alvo 7,24% no período. Quando você pensa em retorno-alvo próprio ("quero 15% ao ano") ou quando não há taxa de referência.
  • O otimizador maximiza o objetivo escolhido garantindo pelo menos esse retorno acumulado no período.
  • Se a meta for inatingível com os ativos e limites atuais, o sistema não falha: retorna a carteira de maior retorno possível e avisa que a meta não foi atingida.

⚠️ A meta relativa exige referência maior que zero. Sem referência, o alvo vira 0 × (1 + Meta) = 0 e a restrição não exige nada. É justamente esse buraco que a meta absoluta preenche — ela funciona independentemente da referência.

⚠️ A meta absoluta é absoluta, não "acima da referência". Com meta absoluta de 30% e referência de 19% ao ano, o alvo é 30% ao ano (e não 49%). Se você quer "x% acima da referência", use o modo relativa.

💡 Meta absoluta e os objetivos do Excesso são independentes. Nos objetivos "Linearidade do Excesso" e "Sharpe do Excesso", o objetivo trabalha sobre o excesso (carteira − referência), enquanto a meta é uma restrição sobre o retorno total. A combinação significa: "entre as carteiras que rendem pelo menos X ao ano, escolha a de melhor excesso sobre a referência". Como esses objetivos costumam superar bastante o alvo, é comum a meta absoluta ficar folgada.

💡 A conversão anual→período é exata e usa a mesma convenção do otimizador (252 pregões): exigir o alvo equivale a exigir retorno anualizado ≥ meta. A mensagem de conclusão informa o alvo, o retorno obtido no período e, no modo absoluto, também o retorno anualizado.

4.5 Executar a Otimização

Clique em 🚀 OTIMIZAR PORTFÓLIO para iniciar o processo. Uma janela de progresso será exibida enquanto o algoritmo executa. Ao concluir, o programa navegará automaticamente para a aba Resultados.

💡 Se o solver não convergir plenamente mas encontrar uma carteira viável, o programa exibe "Otimização concluída com ressalvas" (aviso, não erro) e preenche os resultados normalmente. Ver a seção 12.7 — Degradação Graciosa.

5. Aba Avançado - Restrições Individuais

Esta aba permite definir limites de peso específicos para ativos individuais, sobrescrevendo os limites globais configurados na aba Configuração para aqueles ativos específicos.

5.1 Habilitar Restrições Individuais

  • Marque o checkbox 'Habilitar limites específicos para ativos selecionados'.
  • Clique em 📋 Configurar Restrições Individuais para abrir a janela de configuração.

5.1.1 Importar Restrições de Arquivo (Excel/CSV)

Em vez de digitar os limites manualmente, você pode importá-los de uma planilha com o botão 📂 Importar Restrições (Excel/CSV). É especialmente útil quando alguém já lhe entrega os pesos de uma carteira pronta.

Formatos aceitos (nomes de coluna flexíveis, sem diferenciar maiúsculas/minúsculas):

  • Ativo, Min, Max — define faixas de mínimo e máximo por ativo.
  • Ativo, Peso — fixa mínimo = máximo = peso. Quando os pesos somam 100%, o otimizador é forçado exatamente àquela composição — o software passa a atuar como um analisador do portfólio informado.

Detalhes da leitura:

  • Os valores são interpretados em percentual (ex.: 30 = 30%); se todos forem ≤ 1, são tratados como fração (ex.: 0.30 = 30%).
  • Aceita CSV com separador ,, ; ou tabulação, e vírgula decimal (ex.: 30,5).
  • Ao importar, o sistema seleciona automaticamente na aba Dados exatamente os ativos do arquivo que existem nos dados carregados, ativa as restrições individuais e preenche o resumo. Ativos do arquivo que não existirem nos dados são reportados e ignorados.

💡 Carregue os dados (aba Dados) antes de importar, pois o sistema casa os ativos do arquivo com os ativos disponíveis na planilha carregada.

O que está na aba Avançado é imperativo

Uma regra definida na aba Avançado tem de ser respeitada. Se algum ativo com regra não estiver selecionado na aba Dados, a regra não seria aplicada — e o otimizador entregaria uma carteira diferente da pedida. Por isso, nesse caso a otimização é recusada com uma mensagem que lista os ativos em falta e como resolver.

O sistema nunca otimiza ignorando o que você definiu ali, nem passa por cima da sua seleção na aba Dados: quando as duas se contradizem, ele para e pergunta.

⚠️ Isso não convive com o recálculo automático do ranking (aba Ranking, seção 7.5). As duas coisas se contradizem: uma diz "quero exatamente estes ativos com estes pesos", a outra diz "escolha os ativos por mim". Com as duas ligadas, o ranking refaz a seleção ao otimizar, ativos com regra ficam de fora, e a otimização é recusada.

✅ Como proceder:

  • Para usar a carteira/regras do Avançado: desmarque 🔄 Recalcular o ranking... antes de cada otimização na aba Ranking.
  • Para deixar o ranking escolher os ativos: limpe as restrições individuais na aba Avançado.

💡 Por que a recusa, e não um simples aviso: antes o programa seguia em frente, e o resultado parecia certo. Os ativos da carteira que o ranking mantinha conservavam o peso travado, então a composição saía parecida com a original — só faltavam os que o ranking havia descartado. Num teste com 19 ativos a 5,26% cada, 17 sobreviveram com peso idêntico e 2 sumiram sem deixar rastro. Um resultado errado com aparência de certo é pior que um erro na tela.

5.2 Janela de Configuração

A janela exibe todos os ativos selecionados na aba Dados. Para cada ativo:

  • Marque o checkbox 'Usar limites específicos': ativa os campos de mínimo e máximo para aquele ativo.
  • Mín (%): peso mínimo individual (pode ser diferente do global).
  • Máx (%): peso máximo individual.

Ferramentas de ação rápida disponíveis na janela:

  • Buscar: filtra a lista de ativos por nome em tempo real.

  • Aplicar Globais: copia os limites globais para todos os ativos marcados.

  • Limpar Todos: desmarca todas as restrições individuais.

  • Lote - Mín / Máx + Aplicar aos Selecionados: define um valor de mínimo e máximo em lote para todos os ativos marcados.

  • Após configurar, clique em ✅ Aplicar Configuração. Um resumo das restrições configuradas será exibido na aba Avançado.

💡 As restrições individuais têm prioridade sobre os limites globais. Se um ativo tem restrição individual definida, os valores globais são ignorados para ele.

6. Aba Short/Hedge - Posições Vendidas

Esta aba permite incluir posições vendidas (short selling) no portfólio, úteis para estratégias de hedge ou para explorar movimentos de queda em ativos específicos.

6.1 Habilitar Posições Short

  • Marque o checkbox 'Habilitar posições short/hedge (venda a descoberto)'.
  • Clique em 📋 Selecionar Ativos para Short para abrir a janela de seleção.

💡 Os ativos disponíveis para short são aqueles que NÃO estão selecionados como ativos principais na aba Dados. Portanto, é necessário ter selecionado os ativos long antes de configurar os shorts.

6.2 Janela de Seleção de Ativos Short

A janela lista todos os ativos disponíveis para posições vendidas. Para cada ativo:

  • Marque o checkbox: inclui o ativo como posição short.
  • Peso (%): informe o peso em percentual NEGATIVO (ex.: -10 para uma posição short de 10%). O sistema valida automaticamente que o valor seja negativo.

Ferramentas disponíveis:

  • Buscar: filtra ativos por nome.
  • Selecionar Todos / Limpar Todos: ações em lote.
  • Peso padrão + Aplicar aos Selecionados: define um peso padrão para todos os ativos marcados de uma vez.

⚠️ O peso dos ativos short deve obrigatoriamente ser NEGATIVO. O sistema rejeitará a configuração se qualquer peso for zero ou positivo.

6.3 Comportamento na Otimização

Quando há posições short configuradas:

  • Os ativos short são incluídos no otimizador com seus pesos fixos (conforme configurado).
  • O otimizador distribui os 100% restantes entre os ativos long selecionados.
  • Os pesos negativos aparecem na composição do portfólio identificados como 'SHORT'.
  • O cálculo de 'Peso Atual' na tabela de composição considera apenas o valor das posições long para normalização.
  • A referência deixa de ser descontada. A curva da carteira (comprados − vendidos) já é o excesso; descontar a taxa de referência de novo contaria o índice duas vezes. Por isso, com posição vendida, a otimização e a aba Resultados tratam a carteira como sem referência: Sharpe e Sortino não descontam nada, e as linhas Taxa Ref e Excesso aparecem zeradas (o Excesso é igual ao Total). O gráfico mostra só a curva da carteira.
  • Os objetivos com taxa de referência ficam indisponíveis (Linearidade do Excesso e Sharpe do Excesso). Se um deles estava escolhido, o programa volta para 'Maximizar Sharpe Ratio'; ao desligar os vendidos, eles reaparecem.
  • A Auto-Otimização segue as mesmas duas regras (ver 10.2, Posições Vendidas).

7. Aba Ranking - Classificação de Ativos

O sistema de ranking calcula um índice de qualidade para cada ativo com base em três dimensões: tendência (inclinação), estabilidade (desvio padrão) e correlação com a referência. Isso permite selecionar automaticamente os melhores ativos para a otimização.

7.1 Metodologia do Ranking

O cálculo ocorre em 4 passos internos:

  • Diferença diária: para cada ativo, calcula-se a diferença entre o retorno diário do ativo e o retorno da referência (ativo − referência, dia a dia).
  • Integral acumulada: soma acumulada (cumsum) das diferenças diárias. Representa a evolução do desempenho relativo ao longo do tempo.
  • Parâmetros: regressão linear da integral acumulada (slope = inclinação, R² = qualidade) e desvio padrão das diferenças diárias. A correlação é calculada entre a integral acumulada do ativo e a da referência.
  • Índice bruto e normalização: os três componentes são normalizados e combinados com pesos configuráveis. O resultado final é normalizado de 0 a 1.

Fórmula do índice:

Índice = [P_inc × Inclinação_norm + P_desv × (1 − Desvio_norm) + P_cor × Correlação] ÷ (P_inc + P_desv + P_cor)

Quando não há taxa de referência

O ranking é relativo por natureza: ele mede cada ativo contra alguma coisa. Sem referência definida, esse papel passa a ser da linha do zero — a diferença "ativo − referência" vira o próprio retorno do ativo, e o índice passa a medir a qualidade da evolução dele por si só (sobe de forma consistente? em linha reta?).

A correlação deixa de existir nesse caso (não há com o que correlacionar), então esse componente sai da conta e seu peso é redistribuído:

Índice = [P_inc × Inclinação_norm + P_desv × (1 − Desvio_norm)] ÷ (P_inc + P_desv)

Na tabela, a coluna Correlação aparece como —, e o cabeçalho informa "sem referência (medido contra a linha do zero)".

Pesos sem critério: o programa avisa

Os pesos precisam distinguir alguma coisa. Duas combinações não distinguem nada, e o programa barra com explicação em vez de entregar um ranking sem sentido (todos os ativos empatariam em 0,5, e o filtro de Score passaria a cortar todos ou nenhum):

  • Os três pesos em zero — nenhum critério.
  • Só a Correlação com peso, e a base sem referência — a correlação não existe sem referência (ver acima).

O aviso aparece tanto ao calcular o ranking quanto ao iniciar a Auto-Otimização.

⚠️ Corrigido na versão atual: antes, sem referência, o programa tomava a primeira coluna como referência de qualquer jeito. Aquele ativo desaparecia do ranking sem aviso — e, como a Auto-Otimização escolhe os ativos pelo ranking, ele nunca podia entrar na carteira, em nenhum step. Se você rodou auto-otimizações sem referência em versões anteriores, vale repetir: os resultados mudam.

7.2 Configurar e Calcular

  • Marque o checkbox '🤖 Ativar ranking automático de ativos'. O painel de configuração aparecerá.
  • Ajuste os pesos dos três componentes com os controles deslizantes (valores entre 0 e 1):
    • 📈 Peso Inclinação: importância da tendência de alta relativa à referência. Maior peso favorece ativos com retorno consistentemente superior ao benchmark.
    • 📊 Peso Estabilidade: importância da baixa volatilidade relativa. Maior peso favorece ativos que superam a referência de forma estável, sem grandes oscilações.
    • 🎯 Peso Correlação: importância da correlação com a referência. Valores negativos de correlação podem indicar ativos com potencial de hedge.
    • Padrão: Inclinação 0,33, Estabilidade 1,00, Correlação 0,60.
  • Clique em 🔄 Calcular Ranking. O resultado aparece na tabela com até 20 ativos exibidos.

7.3 Tabela de Resultados

Coluna Descrição
Posição Classificação do ativo (1 = melhor).
Ativo Nome do ativo conforme cabeçalho da planilha.
Índice Score normalizado entre 0 e 1 (1 = melhor desempenho relativo).
Inclinação Inclinação normalizada da regressão linear da integral acumulada.
R² Coeficiente de determinação da regressão (qualidade da tendência linear).
Correlação Correlação entre as integrais acumuladas do ativo e da referência.
Desvio Desvio padrão normalizado das diferenças diárias ativo−referência.

7.4 Seleção Automática por Score

Abaixo da tabela, defina um intervalo de score para selecionar ativos automaticamente:

  • Score mínimo: limiar inferior do índice (ex.: 0.70 para selecionar apenas ativos acima de 70% do máximo).

  • Score máximo: limiar superior (geralmente 1.0 para incluir os melhores).

  • Clique em ✅ Selecionar Ativos por Score. O programa selecionará automaticamente na listbox da aba Dados apenas os ativos dentro do intervalo definido e navegará para a aba Configuração.

💡 A seleção por score respeita as configurações de short selling e restrições individuais já definidas. Essas configurações são preservadas mesmo após a atualização da seleção de ativos.

💡 A faixa de score que você digitar é preservada quando o ranking é recalculado. (Antes ela voltava ao padrão 0,70–1,00 a cada recálculo, apagando o critério em silêncio.)

7.5 Recálculo Automático Antes de Otimizar

Na caixa ⚙️ Configurar Pesos dos Parâmetros existe a opção 🔄 Recalcular o ranking e reselecionar os ativos antes de cada otimização, marcada por padrão.

Estado Ao clicar em Otimizar
Marcada (padrão) O ranking é refeito para o período processado no momento, e os ativos são reselecionados pela faixa de score.
Desmarcada Vale a lista que estiver selecionada na aba Dados, seja ela de qual período for (comportamento anterior).

Só tem efeito com 🤖 Ativar ranking automático de ativos marcado. Sem isso, a otimização usa a seleção manual, como sempre.

Para que serve. Num walk-forward feito à mão — você avança a janela um mês, processa e otimiza, repetidamente — o ranking muda a cada janela, e a seleção da janela anterior fica velha. Sem essa opção, o programa aceitava a lista antiga sem dizer nada: nenhum erro, nenhum aviso, e o resultado saía com cara de certo. Bastava esquecer de clicar em Calcular Ranking + Selecionar Ativos por Score.

Exemplo real da diferença, movendo a janela de 01/01/23–31/12/23 para 01/02/23–31/01/24 (um único mês a mais):

Ativo Score na 1ª janela Score na 2ª janela
BOM O ANO TODO 1,000 1,000
DISPARA EM JAN24 0,067 0,000
MEDIANO 0,000 0,252

Segundo e terceiro lugares trocaram de posição.

Ao final da otimização, a mensagem de sucesso informa que o ranking foi recalculado e quantos ativos entraram — para você não confundir a carteira obtida com a lista que estava marcada antes.

⚠️ Se a faixa de score devolver menos de 2 ativos naquele período, a otimização é interrompida com explicação (alargue a faixa, ou desmarque o recálculo automático). Melhor parar do que otimizar sobre uma seleção que não faz sentido.

⚠️ Não use esta opção junto com restrições individuais ou uma carteira importada na aba Avançado (seção 5.1.1). As duas se contradizem: o Avançado fixa ativos e pesos, o recálculo escolhe os ativos por conta própria. Com as duas ligadas, o ranking substitui a seleção, ativos com regra ficam de fora e a otimização é recusada com a explicação e as duas saídas possíveis. Antes de carregar uma carteira, desmarque esta caixa; antes de voltar a usar o ranking, limpe as restrições individuais.

8. Aba Resultados - Análise do Portfólio

Após a otimização, esta aba exibe um painel completo com três colunas de métricas lado a lado e a composição do portfólio com o gráfico de evolução.

8.1 Coluna IN-SAMPLE (Otimização)

Métricas calculadas sobre o período de treinamento (janela de otimização):

Métrica Descrição
Retorno Total (%) Retorno acumulado do portfólio no período de otimização em base zero.
Retorno Anualizado (%) Retorno total anualizado de forma composta em 252 pregões: (1 + R)^(252/pregões) − 1.
Sharpe Ratio Excesso de retorno anualizado dividido pela volatilidade anualizada.
Volatilidade (%) Desvio padrão anualizado dos retornos diários (×√252).
VaR 95% Diário Value at Risk: perda máxima esperada em 95% dos dias (paramétrico).
CVaR 95% Diário Conditional VaR: perda média esperada além do VaR (tail risk).
R² Qualidade da linearidade do retorno acumulado (regressão linear).
Taxa Ref Período (%) Retorno acumulado da taxa de referência no período.
Taxa Ref Anualizada (%) Taxa de referência do período anualizada da mesma forma (252 pregões).
Excesso Período (%) Curva do portfólio menos curva da referência (a curva verde do gráfico) no período.
Excesso Anualizado (%) O Excesso Período anualizado a partir da própria curva do excesso: (1 + Excesso)^(252/pregões) − 1.
Excesso/Ref (%) Excesso anualizado dividido pela taxa de referência anualizada: quanto o portfólio superou a referência em termos relativos (ex.: 50% = rendeu 50% a mais que a referência).
Pregões Número de pregões do período (contados, sem o dia-base da base zero).

8.2 Coluna OUT-OF-SAMPLE (Validação)

As mesmas métricas calculadas para o período de validação, usando os MESMOS pesos otimizados na fase de treinamento. Este é o teste real de generalização do portfólio.

Os resultados da validação saem direto das curvas do gráfico, por subtração: Total = curva do portfólio no fim da validação − curva no fim da otimização; o mesmo para a referência e para o excesso (curva verde). Assim, Total − Taxa Ref Período = Excesso Período, e uma carteira com a referência vendida a 100% mostra como Total exatamente o Excesso da mesma carteira com a referência. A anualização é a mesma do IN-SAMPLE (composta, 252 pregões contados). Volatilidade e VaR continuam pela variação diária em PU, (1 + curva hoje) / (1 + curva ontem).

Quando a anualização não existe (perda acima de 100 pontos numa curva de excesso), o campo mostra n/d.

💡 Se nenhuma janela de validação foi configurada (ou o período de validação é muito curto), esta coluna exibirá uma mensagem informativa. Configure uma data 'Fim da Análise' na aba Dados para ativar este painel.

8.3 Coluna COMPARAÇÃO

Exibe as diferenças entre out-of-sample e in-sample para as principais métricas:

  • Retorno Anual (diferença): positivo indica que o portfólio performou melhor fora da amostra do que dentro.
  • Sharpe (diferença): chave para avaliar overfitting. Diferenças grandes e negativas sugerem que o modelo foi super ajustado ao período de treino.
  • Volatilidade (diferença): indica se o risco se manteve estável entre os períodos.
  • Resumo / Análise: o sistema emite automaticamente um diagnóstico qualitativo (ex.: 'Boa generalização!' ou 'Cuidado: overfitting?').

8.4 Composição do Portfólio

A tabela abaixo das três colunas exibe todos os ativos com peso significativo (> 0,1%):

Coluna Descrição
Ativo Nome do ativo.
Peso Inicial (%) Peso otimizado na data de início do portfólio.
Peso Atual (%) Peso estimado ao final do período, considerando a valorização relativa de cada ativo.
Tipo LONG (posição comprada) ou SHORT (posição vendida).

As linhas de rodapé da tabela exibem o TOTAL LONG, TOTAL SHORT (quando aplicável) e a VARIAÇÃO do peso long entre o início e o fim do período.

8.5 Gráfico de Evolução

O gráfico à direita da composição exibe:

  • Linha azul: retorno acumulado do portfólio.
  • Linha laranja (tracejada): retorno acumulado da taxa de referência (quando disponível).
  • Linha verde (pontilhada): excesso de retorno acumulado (portfólio − referência).
  • Linha vertical vermelha: marca o fim do período de otimização e início do out-of-sample.

8.6 Exportação

  • 💾 Exportar CSV: salva a tabela de composição do portfólio (Ativo, Peso Inicial, Peso Atual, Tipo) em formato CSV.
  • 📊 Exportar Excel: salva a mesma tabela em formato .xlsx.

9. Aba Retornos Mensais

Esta aba exibe os retornos do portfólio organizados em tabela pivot (anos nas linhas, meses nas colunas), cobrindo o período completo configurado (otimização + validação).

9.1 Aba Retornos do Portfólio

Exibe os retornos mensais percentuais calculados pela metodologia de crescimento relativo em base zero:

  • Meses: Jan a Dez, exibidos como colunas.
  • Total Anual: retorno composto do ano, calculado pela multiplicação dos fatores mensais: (1+r₁)×(1+r₂)×...×(1+r₁₂) − 1.
  • Ícone 📈: indica ano com retorno médio positivo.
  • Ícone 📉: indica ano com retorno médio negativo.

9.2 Aba Excesso de Retorno

Disponível apenas quando uma taxa de referência foi detectada. Exibe a diferença entre o retorno mensal do portfólio e o retorno mensal da referência. Valores positivos indicam meses em que o portfólio superou o benchmark.

💡 Ambas as tabelas cobrem o período completo (otimização + validação), não apenas o período de treinamento. Isso permite avaliar o desempenho real do portfólio ao longo do tempo inteiro.

10. Aba Auto-Otimização - Walk-Forward

A Auto-Otimização executa automaticamente centenas ou milhares de testes walk-forward, variando sistematicamente os parâmetros de otimização para identificar as combinações mais robustas. É a funcionalidade mais avançada do sistema.

🏛️ A referência é a mesma da aba Dados — a detectada na importação ou a que você escolheu em Alterar Ativo de Referência (seção 3.2.3). Ela alimenta o ranking de cada step, a coluna Ref%, a Meta relativa e os objetivos de excesso. Para não restar dúvida, o cabeçalho desta aba mostra qual referência está em uso: em verde quando há uma, em laranja quando não há (com o aviso de que o Ref% fica em 0% e o ranking passa a medir contra a linha do zero — ver seção 7.1).

🏆 Os pesos do ranking também são os da aba Ranking — Inclinação, Estabilidade e Correlação (seção 7.1). O que você ajustar lá é o que roda aqui, em cada step. O que a Auto-Otimização define por conta própria é apenas o Score Min/Max, que corta a lista já classificada.

⚠️ Corrigido na versão atual: os três pesos ficavam fixos em 0,33 dentro da Auto-Otimização, ignorando os controles da aba Ranking. Dava para ajustá-los, ver a ordem mudar na aba Ranking, rodar a Auto-Otimização e ela usar outra coisa — sem aviso. Na época o padrão dos controles era 0,33 cada; hoje é Inclinação 0,33, Estabilidade 1,00 e Correlação 0,60.

10.1 Conceito de Walk-Forward

O método walk-forward funciona da seguinte forma para cada combinação de parâmetros:

  • Step 1 - Ranking: calcula o ranking de ativos para o período de treinamento atual e filtra os ativos pelo intervalo de score configurado.
  • Step 2 - Otimização: otimiza o portfólio com os ativos selecionados pelo ranking, usando o objetivo e os limites de peso configurados.
  • Step 3 - Validação: aplica os pesos otimizados no período de validação imediatamente seguinte (fora da amostra de treino).
  • Step 4 - Avanço: desloca as janelas no tempo pelo período de rebalanceamento e repete os passos 1 a 3.
  • Step 5 - Acumulação: o retorno de cada step é acumulado para calcular as métricas finais da configuração.

💡 O walk-forward usa os dados BRUTOS (não processados) da planilha original, aplicando a transformação base zero em cada step independentemente. Isso evita vazamento de informação entre períodos.

10.2 Parâmetros de Configuração

Janelas de Otimização

Definem o tamanho do período de treino em cada step:

Opção Dias Corridos
3m 90 dias
6m 180 dias
1a 365 dias
2a 730 dias
3a 1095 dias

Janelas de Validação / Step

Definem ao mesmo tempo a duração do período out-of-sample e a frequência de rebalanceamento:

Opção Dias Corridos
1 semana 7 dias
2 semanas 14 dias
1 mês 30 dias
2 meses 60 dias
3 meses 90 dias

Objetivos de Otimização

Selecione um ou mais objetivos. O sistema testará cada combinação para cada objetivo selecionado:

  • Maximizar Sharpe
  • Maximizar Sortino
  • Minimizar Risco
  • Minimizar Under Water
  • Maximizar Inc/[(1-R²)×Vol]
  • Qualidade da Linearidade
  • Linearidade do Excesso
  • Sharpe do Excesso

Posições Vendidas (Opcional)

Marque 'Habilitar posições short' e clique em 📋 Selecionar Ativos para Short para abrir a janela de seleção. Nela você pode escolher um ou mais ativos para posição vendida, cada um com seu peso em percentual negativo (com busca, seleção em lote e peso padrão, igual à aba Short/Hedge). Os ativos e pesos escolhidos são fixos e aplicados a todos os steps do walk-forward. Um resumo dos shorts configurados aparece na própria aba.

💡 Os candidatos a short são todos os ativos carregados (aba Dados). Em cada step, se um ativo short também tiver sido escolhido como long pelo ranking, ele é tratado apenas como short. Ativos short ausentes no período de um step são ignorados naquele step.

Com posição vendida, a carteira (comprados − vendidos) já é o excesso: a referência não é descontada de novo (otimização, validação e Ref% zerada) e os objetivos do excesso ficam indisponíveis, como na otimização manual (ver 6.3).

Configurações Globais

Parâmetro Descrição
Score Min / Max (0-100) Intervalo do ranking de ativos. Ativos com índice fora deste intervalo são excluídos da otimização em cada step. Valor 0-100 = todos os ativos. Padrão: 75 a 100.
Peso Min (%) / Max (%) Limites globais de peso aplicados em cada step da otimização. Padrão: 0% a 100%.
Pesos na Validação Com que pesos a validação de cada step começa. Otimizados (Peso Inicial), o padrão: os calculados pela otimização do step — é o rebalanceamento. Atuais (Peso Atual): os otimizados depois de andarem com os preços até o fim da otimização — a carteira segue sem rebalancear (para carteiras só compradas, dá os mesmos números das versões anteriores). A escolha fica gravada.
Meta de Retorno Opcional. Marque 'Exigir meta' e escolha o modo: % acima da ref. (relativa) ou % ao ano (absoluta). A meta é aplicada em cada step do walk-forward — na relativa, contra a referência daquele período; na absoluta, convertida para os pregões daquela janela. O cumprimento por step é reportado na coluna Meta% da tabela de resultados.

Como cada step é medido

Cada step otimiza na sua janela (base zero no início dela) e, na validação, recomeça a base zero no primeiro dia da validação, com os pesos escolhidos acima. Os resultados saem direto das curvas, por subtração — carteira, referência e excesso partem do zero no mesmo dia —, sem divisões. Como cada validação é medida sobre o capital do início dela, os steps se encadeiam multiplicando (1 + retorno de cada step). Uma perda acima de 100% (possível com vendido) zera o capital.

A anualização (do step e da configuração) é composta em 252 pregões contados — a soma dos pregões de validação dos steps —, nunca por subtração de datas. As janelas (6 meses, 1 mês...) continuam sendo definidas em dias corridos.

10.3 Estimar e Executar

  • Clique em 🧮 Calcular para ver uma estimativa do número de configurações, testes totais, dias do período e steps por configuração antes de executar.
  • Clique em 🚀 INICIAR AUTO-OTIMIZAÇÃO. O processo roda em thread separada para não travar a interface.
  • O status no topo direito da aba atualiza em tempo real: configuração atual sendo testada, resultado (✅ ou ❌) e número de steps.

⚠️ Para dados com muitos anos e janelas curtas (ex.: 1 semana), o número de steps pode ser muito alto. Use a estimativa antes de executar para evitar processos muito longos.

10.4 Tabela de Resultados

Ao concluir, a tabela exibe todas as configurações válidas ordenadas pelo Sharpe Ratio (maior para menor):

Coluna Descrição
# Posição na classificação (1 = melhor Sharpe).
Otimização Janela de otimização usada.
Rebalanc. Janela de validação/rebalanceamento.
Objetivo Objetivo de otimização.
N_Ativos Número médio de ativos por step.
Sharpe Sharpe Ratio final acumulado (retorno anualizado − taxa ref) ÷ volatilidade média.
Ret% Retorno anualizado acumulado de todos os steps (fora da amostra).
Meta% Percentual de steps que cumpriram a Meta dentro da janela de otimização. Exibe "—" quando a meta não foi usada. Ver interpretação abaixo.
Ref% Taxa de referência anualizada acumulada.
Vol% Volatilidade média dos steps.
VaR% VaR 95% diário médio dos steps (perda esperada nos piores 5% dos dias). Risco de cauda.
>Ref% Percentual de períodos (steps de rebalanceamento) em que o retorno superou a taxa de referência do período.
>0% Percentual de períodos (steps de rebalanceamento) com retorno positivo em termos absolutos.

💡 Cabeçalhos abreviados com tooltip: passe o mouse sobre qualquer título de coluna para ver a explicação completa do que ela mede.

💡 Tabela ordenável: clique em qualquer cabeçalho para reordenar por aquela coluna; clique de novo para inverter. A ordenação é numérica (e não alfabética), então 10 vem depois de 3 e 2.101 depois de 18.5%, como esperado.

Como interpretar a coluna Meta%

A coluna Meta% mede o cumprimento da meta onde o otimizador podia agir (dentro da amostra), enquanto Ret% mede o resultado fora da amostra. Cruzar as duas separa duas causas bem diferentes de um retorno abaixo do alvo:

Meta% Leitura
100% com Ret% abaixo do alvo A meta foi batida in-sample, mas não se sustentou fora da amostra. Típico dos minimizadores de risco (Minimizar Risco, Under Water): a meta é restrição ativa, a carteira encosta exatamente no alvo e fica sem folga — qualquer degradação out-of-sample derruba o número.
Abaixo de 100% Em alguns steps o alvo era inatingível com os limites vigentes, valendo o fallback de "maior retorno possível".
"—" A meta não estava em uso nessa execução.

💡 Objetivos que buscam retorno por natureza (Sharpe, Sortino) tendem a passar longe do alvo in-sample, guardando folga que sobrevive fora da amostra. Se a meta relativa está sendo cumprida in-sample mas não se sustenta, considere pedir uma margem maior.

10.5 Exportação dos Resultados

Ambas as exportações gravam valores numéricos de verdade (não texto), respeitando a ordenação atual da tabela — o que você vê é o que é exportado.

  • 💾 Exportar CSV: separador ; e decimal , (padrão brasileiro, que o Excel pt-BR abre com duplo clique sem passar pelo assistente de importação). Os percentuais saem já multiplicados por 100, coerentes com o cabeçalho (%).
  • 📊 Exportar Excel: percentuais gravados como percentual nativo do Excel (formatos 0,0%, 0,00%), Sharpe com formato 0,000, Rank e N_Ativos como inteiros. Inclui cabeçalho em negrito, painel congelado na primeira linha, autofiltro e ajuste automático da largura das colunas.

💡 Como os valores são números reais, o separador decimal exibido é o do seu sistema (vírgula no Brasil) e as células podem ser somadas, ordenadas e usadas em fórmulas normalmente. Quando a meta não é usada, a célula de Meta_OK fica vazia (em vez de "—"), para não atrapalhar cálculos.

11. Fluxo de Trabalho Recomendado

Para obter os melhores resultados, siga esta sequência:

Etapa Ação Aba
1 Prepare a planilha Excel com datas, benchmark e ativos — ou importe de uma das fontes online. -
2 Verifique se o benchmark foi detectado corretamente; se não, use 🏛️ Alterar Ativo de Referência. 📁 Dados
3 Configure as janelas temporais (sugestão: 70% treino, 30% validação) e processe. 📁 Dados
4 Selecione os ativos de interesse ou use o ranking para seleção automática. 📁 Dados / 🏆 Ranking
5 Defina o objetivo de otimização e os limites globais de peso. ⚙️ Configuração
6 Se necessário, configure restrições individuais ou posições short. 🔧 Avançado / 🔄 Short
7 Execute a otimização e analise os resultados in-sample e out-of-sample. 📈 Resultados
8 Verifique os retornos mensais para consistência temporal. 📅 Mensais
9 Use a Auto-Otimização para explorar sistematicamente outros parâmetros. 🤖 Auto-Otimização
10 Exporte os resultados da composição e da auto-otimização para análise externa. 📈 / 🤖

12. Dicas e Boas Práticas

12.1 Preparação dos Dados

  • Certifique-se de que não há datas duplicadas na planilha.
  • Ativos com dados faltantes no início do período serão automaticamente removidos. Se um ativo começou a ser negociado depois dos demais, inclua-o a partir de sua primeira data disponível ou remova-o da planilha.
  • Utilize sempre preços de fechamento (ou cotas) ajustados por proventos para evitar distorções nos retornos calculados. Na importação da B3, marque o 🧮 Ajuste por eventos corporativos (seção 3.2.1).
  • Nomeie as colunas dos ativos com identificadores claros (ex.: ticker da bolsa) para facilitar a interpretação dos resultados.

12.2 Seleção de Janelas Temporais

  • A proporção 70/30 (70% treino, 30% validação) é um ponto de partida razoável, mas pode ser ajustada conforme o tamanho da série histórica disponível.
  • Para períodos curtos (menos de 2 anos de dados), prefira janelas de otimização menores (3 a 6 meses) para garantir steps suficientes na auto-otimização.
  • Períodos de validação muito curtos (menos de 60 dias) podem não ser estatisticamente representativos.

12.3 Interpretação do Overfitting

  • Uma diferença grande e negativa no Sharpe entre out-of-sample e in-sample é o principal sinal de overfitting.
  • O objetivo 'Qualidade da Linearidade' (R²) tende a gerar modelos mais robustos e com menor overfitting do que Sharpe puro.
  • Prefira janelas de otimização mais longas (1 a 2 anos) para reduzir o risco de overfitting ao ruído de curto prazo.

12.4 Auto-Otimização

  • Comece com poucas combinações para validar o processo antes de executar centenas de configurações.
  • Um Sharpe alto na Auto-Otimização não garante desempenho futuro. Observe também a consistência (% de períodos positivos) e a estabilidade da volatilidade.
  • Configurações com janelas muito curtas (ex.: 1 semana de rebalanceamento) tendem a gerar custos de transação elevados em carteiras reais.

12.5 Ranking de Ativos

  • O peso de correlação pode ser ajustado para zero se você não quiser que a relação com o benchmark influencie o ranking.
  • Correlações negativas podem ser desejáveis para ativos de hedge: ajuste o peso de correlação para valores negativos não é suportado diretamente, mas ativos com correlação negativa obterão scores menores, o que pode ser usado para identificá-los e inclui-los como short.
  • Recalcule o ranking sempre que mudar o período de análise, pois os parâmetros são recalculados com base nos dados do período configurado. A opção de recálculo automático (seção 7.5) faz isso por você.
  • Ranking e regras do Avançado não convivem. Se você importou uma carteira ou definiu restrições individuais na aba Avançado, desligue o recálculo automático do ranking antes de otimizar — com os dois ligados, o ranking refaz a seleção, ativos com regra ficam de fora e a otimização é recusada. Ver seções 5.1.1 e 7.5.

12.6 Robustez da Otimização (Multi-Start)

Alguns objetivos não-lineares (como a Linearidade do Excesso) podem, em certas configurações, fazer o otimizador "travar" no ponto de partida e devolver uma carteira de pesos iguais (todos os ativos com o mesmo percentual). Para evitar isso, o solver detecta automaticamente esse travamento e reinicia a busca a partir de vários pontos aleatórios, ficando com o melhor resultado.

  • Sinal de travamento (versões antigas): se você vir todos os ativos com peso exatamente igual (ex.: todos com 1,67%), é sinal de que a otimização não convergiu. Com o multi-start isso é corrigido automaticamente.
  • Custo: o multi-start só é acionado quando há travamento, então otimizações que convergem normalmente não ficam mais lentas. Nos casos travados, a otimização pode demorar mais alguns segundos (especialmente com muitos ativos), pois testa vários reinícios.
  • Reprodutibilidade: os reinícios usam uma semente fixa, então a mesma configuração sempre produz o mesmo resultado.

12.7 Degradação Graciosa (em vez de "Otimização falhou")

Em janelas difíceis — tipicamente quando há mais ativos do que dias no período de otimização — o solver pode não convergir formalmente e retornar a mensagem Positive directional derivative for linesearch. Antes, isso abortava a otimização sem mostrar resultado algum.

Agora, quando os pesos em mãos formam uma carteira viável (respeitam os limites e somam 100% após normalização), o sistema entrega essa carteira com um aviso, em vez de falhar:

  • Na otimização manual, aparece a mensagem "Otimização concluída com ressalvas" (aviso, não erro), e a aba Resultados é preenchida normalmente com todas as métricas.
  • Na Auto-Otimização, a ressalva é registrada no log do step e o processo segue para os próximos steps.
  • Se os pesos realmente não forem aproveitáveis, o erro original continua sendo exibido.
  • Há também um aviso específico quando o objetivo termina em região inválida (ex.: inclinação negativa), caso em que a carteira devolvida pode estar próxima do ponto de partida.

⚠️ Causa de raiz: ter mais ativos do que dias torna o problema matematicamente mal-posto — existem infinitas carteiras que parecem ótimas dentro da amostra, e a maioria é ajuste ao ruído. A degradação graciosa evita a interrupção, mas o remédio de verdade é reduzir o universo de ativos (use o Ranking por Score) para que ele fique confortavelmente abaixo do número de dias da janela.

12.8 Desempenho

O motor de cálculo passou por otimizações que reduziram bastante o tempo das rodadas, sem alterar nenhum resultado:

  • Caminho de cálculo enxuto: para os objetivos simples (Sharpe, Sortino, Under Water, Minimizar Risco), cada avaliação dentro do laço do solver calcula apenas o necessário, sem VaR, CVaR nem regressões. As métricas completas continuam sendo calculadas uma única vez, ao final, sobre os pesos ótimos — a aba Resultados e as tabelas não mudam.
  • Sortino suavizado: o downside deviation usa o semi-desvio clássico de Sortino & Price, √(média(mín(retorno,0)²)), que é diferenciável. A forma anterior (desvio-padrão apenas do subconjunto de dias negativos) tinha "quinas" que deixavam o solver lento e sujeito a falhas de convergência.
  • Regressão por fórmula fechada: a inclinação e o R² usados por HC10, Linearidade do Excesso e Sharpe do Excesso são calculados diretamente, em vez de via scipy.stats.linregress. O resultado é idêntico (diferença ~1e-15, ruído de ponto flutuante) e o cálculo de métricas completas ficou cerca de 5× mais rápido.

💡 Se você usava versões anteriores, note que os valores de Sortino mudaram de magnitude por causa da nova fórmula (o denominador passou a ser calculado sobre todos os períodos). O ranking relativo entre carteiras se mantém.

13. Glossário

Termo Definição
Base Zero Transformação dos preços em retornos diários divididos pelo preço inicial: (Pn − P{n-1}) ÷ P_1. Permite comparar ativos com escalas de preço diferentes.
Integral Acumulada Soma acumulada (cumsum) dos retornos diários em base zero. Representa a evolução do retorno relativo ao longo do tempo.
In-Sample Período usado para calibrar/treinar o modelo. Os pesos são otimizados neste intervalo.
Out-of-Sample Período de validação, fora do intervalo de treinamento. Avalia se o modelo generaliza bem para dados não vistos.
Walk-Forward Metodologia de backtest que simula a operação real do portfólio: treina em uma janela, valida na seguinte, avança no tempo e repete.
Sharpe Ratio (Retorno anualizado − Taxa de referência anualizada) ÷ Volatilidade anualizada.
Sortino Ratio Semelhante ao Sharpe, mas divide o excesso de retorno apenas pela volatilidade de queda (downside deviation), ignorando as oscilações de alta.
Downside Deviation Semi-desvio-padrão das perdas: √(média(mín(retorno, 0)²)), anualizado. Denominador do Sortino.
Under Water (Total) Soma de todos os retornos diários negativos do período; em valor absoluto, o total de perdas acumuladas. Medida de risco assimétrica — pune apenas queda, nunca alta.
Sharpe do Excesso Inclinação da regressão do excesso acumulado dividida pela volatilidade do excesso. É a Linearidade do Excesso sem o fator (1 − R²).
Meta de Retorno Retorno mínimo exigido do portfólio, combinado ao objetivo escolhido. Em dois modos: relativa (Referência × (1 + Meta ÷ 100)) ou absoluta ((1 + Meta)^(pregões ÷ 252) − 1, independente da referência).
Multi-Start Estratégia do solver que reinicia a otimização a partir de vários pontos iniciais quando detecta travamento, escapando de ótimos locais e devolvendo o melhor resultado.
Degradação Graciosa Comportamento do sistema quando o solver não converge formalmente: em vez de abortar, entrega a melhor carteira viável encontrada (dentro dos limites e somando 100%) acompanhada de um aviso.
In-Sample vs Out-of-Sample (Meta) A meta é exigida dentro da janela de otimização; o Ret% da tabela mede o resultado fora dela. A coluna Meta% mostra o cumprimento in-sample, permitindo distinguir "alvo inatingível" de "alvo atingido que não se sustentou".
VaR 95% Value at Risk: estimativa paramétrica da perda máxima esperada em 95% dos dias (μ − 1,65σ).
CVaR 95% Conditional VaR: média das perdas nos 5% piores dias. Mede o risco de cauda (tail risk).
R² Coeficiente de determinação da regressão linear do retorno acumulado. Mede a linearidade da evolução do portfólio (valores próximos de 1 indicam tendência mais linear).
Overfitting Fenômeno em que o modelo se ajusta excessivamente ao período de treino e não generaliza para novos dados.
Benchmark / Taxa de Referência Índice ou taxa usada como referência de desempenho (CDI, SELIC, IBOVESPA etc.).
Short Selling Venda de um ativo que não se possui, apostando na queda de seu preço. Representado por pesos negativos no portfólio.
Score de Ranking Índice normalizado entre 0 e 1 que representa a qualidade relativa de um ativo com base em tendência, estabilidade e correlação.

About

Otimizador de carteiras de ações, FIIs e fundos com dados da B3, CVM e Yahoo: Sharpe, Sortino, linearidade do excesso, posições vendidas (hedge) e walk-forward (auto-otimização)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages