The problem
O problema
Consolidated performance across four institutions is arithmetic nobody wants to do monthly, so it doesn't get done. And without it you can't answer basic questions: what's my real allocation, what's actually paying me, am I drifting away from the mix I chose.
Consolidar a rentabilidade de quatro instituições é uma conta que ninguém quer fazer todo mês, então ela não é feita. E sem ela não dá para responder o básico: qual é minha alocação real, o que está me pagando de fato, se estou me afastando do mix que escolhi.
Collection
Coleta
The brokerage side is the awkward part — there's an investor API, but reaching it means a real login. A headless browser drives the authentication and completes a PKCE token exchange; tokens are cached and refreshed rather than re-earned on every run, because logging in repeatedly is both slow and a good way to get rate-limited.
A corretora é a parte chata: existe uma API para o investidor, mas chegar nela exige um login de verdade. Um navegador headless conduz a autenticação e completa uma troca de token PKCE; os tokens ficam em cache e são renovados em vez de conquistados de novo a cada execução, porque logar várias vezes é lento e um bom jeito de levar rate limit.
Around that sit quieter collectors: daily quotes, USD/BRL and EUR/BRL from the central bank's PTAX series, Treasury bond pricing, exchange balances across spot and earn, and a monthly manual entry path for fixed income that has no API at all. Not everything can be automated, and pretending otherwise leaves a hole in the data.
Em volta ficam coletores mais tranquilos: cotações diárias, USD/BRL e EUR/BRL da série PTAX do Banco Central, preços do Tesouro Direto, saldos da exchange em spot e earn, e uma entrada manual mensal para a renda fixa que não tem API nenhuma. Nem tudo dá para automatizar, e fingir que dá deixa um buraco nos dados.
Modelling
Modelagem
Keeping raw immutable means a parsing bug is a re-run, not a re-collection — which matters when re-collection involves logging into a bank.
Manter o raw imutável faz um bug de parse virar só uma nova execução, não uma nova coleta, o que importa quando coletar de novo significa logar num banco.
script_runs, bottom right, is the execution log.script_runs, no canto inferior direito, é o log de execuções.The part that makes it useful
A parte que torna isso útil
Storage alone doesn't change behaviour. What does is the layer on top: a screener that scores roughly 170 tickers across Brazilian, US, European, and Asian markets daily against Graham, Greenblatt, Bazin, and Lynch criteria; twelve-month dividend projections per holding; rebalancing-drift alerts when allocation wanders from target; and weekly and monthly performance digests. All of it arrives in Discord, because a dashboard I have to remember to open is a dashboard I don't open.
Só guardar os dados não muda comportamento. O que muda é a camada de cima: um screener que pontua todo dia cerca de 170 tickers dos mercados brasileiro, americano, europeu e asiático pelos critérios de Graham, Greenblatt, Bazin e Lynch; projeções de dividendos de doze meses por ativo; alertas de desvio de rebalanceamento quando a alocação foge da meta; e resumos semanais e mensais de rentabilidade. Tudo chega no Discord, porque dashboard que eu preciso lembrar de abrir é dashboard que eu não abro.
What it looks like
Como ele é
The daily view is a single page: where the money is, how far each class has drifted from its target, and what to do about it. The table at the bottom is the decision itself: which class to trim and which to top up, and by how much, to get back to the mix I chose.
A visão diária é uma página só: onde está o dinheiro, quanto cada classe se afastou da meta e o que fazer a respeito. A tabela no fim é a própria decisão: qual classe reduzir, qual reforçar e quanto, para voltar ao mix que escolhi.
The analysts that run on their own
Os analistas que rodam sozinhos
Fourteen scheduled jobs do the work a person would otherwise have to remember. Each one has a single question to answer and reports in Discord only when there is something to say.
Catorze jobs agendados fazem o trabalho que, de outro jeito, alguém teria que lembrar de fazer. Cada um responde a uma única pergunta e só se manifesta no Discord quando tem algo a dizer.
- Collectors · quotes, FX, crypto, Treasury bonds and benchmarks (CDI, IBOV, IFIX) every weekday at 18:30, then
dbt run. - Watchdog · price drops over 5%, allocation drifting more than 5 points from target, ex-dividend dates in the next seven days.
- Screener · around 160 liquid stocks in Brazil, the US, Europe and Asia scored daily against Graham, Greenblatt, Bazin and Lynch, with each day's score stored so recommendations can be checked against what happened next.
- Income · the next twelve months of dividends projected per holding from 24 months of payment history.
- Reports · a weekly and a monthly digest: change, best and worst performers, dividends received, drift, benchmarks.
- Coletores · cotações, câmbio, cripto, Tesouro Direto e benchmarks (CDI, IBOV, IFIX) todo dia útil às 18:30, e depois
dbt run. - Vigia · quedas de preço acima de 5%, alocação desviando mais de 5 pontos da meta, datas ex-dividendo nos próximos sete dias.
- Screener · cerca de 160 ações líquidas no Brasil, nos EUA, na Europa e na Ásia pontuadas todo dia por Graham, Greenblatt, Bazin e Lynch, com a nota de cada dia guardada para conferir as recomendações contra o que aconteceu depois.
- Renda · os próximos doze meses de dividendos projetados por ativo a partir de 24 meses de histórico de pagamentos.
- Relatórios · um resumo semanal e um mensal: variação, melhores e piores ativos, dividendos recebidos, desvio, benchmarks.
Operating it
Operação
Every script runs inside a context manager that writes start, end, and outcome to a script_runs table. This sounds like bookkeeping and is actually the most important file in the project: the failure mode of a personal pipeline isn't a crash, it's a collector that silently returns nothing for three weeks while the dashboards keep rendering yesterday's numbers with total confidence.
Todo script roda dentro de um context manager que grava início, fim e resultado numa tabela script_runs. Parece burocracia e, na prática, é o arquivo mais importante do projeto: o jeito de um pipeline pessoal falhar não é um crash, é um coletor que passa três semanas sem trazer nada, em silêncio, enquanto os dashboards seguem mostrando os números de ontem com total confiança.