Tubarões

O primeiro escolhido é o maior.

Cardume padrão

projeto · 25 de out. de 2026

finwatch: o noticiário financeiro de 2026, classificado por probabilidade

Coleta 11 veículos de economia e o BACEN e classifica cada notícia por tema e sentimento segundos depois da coleta, tudo em Workers da Cloudflare. São 194 mil notícias de 2026, por uns 4 centavos de dólar por dia.

finwatch.stater.dev ↗

Queria aprender ciência de dados fazendo um projeto inteiro, da coleta ao gráfico, e escolhi uma pergunta que dá pra responder com dado público: o que a imprensa brasileira está dizendo sobre os bancos em 2026?

O finwatch coleta 11 fontes de notícia (InfoMoney, Valor, Estadão, Exame, a CVM e outras) e 7 séries do Banco Central. Cada notícia é limpa, deduplicada, rotulada com tema e sentimento e agrupada com as matérias da mesma pauta. O resultado vai para um dashboard em finwatch.stater.dev.

Em 25/10/2026 eram 194.002 notícias, 8,7% delas sobre o setor bancário. Na mediana, uma notícia leva 7 segundos entre ser gravada e ganhar rótulo.

Como funciona

O dado bruto é gravado uma vez no R2 e nunca é editado. Tudo que vem depois pode ser jogado fora e refeito. A chave de cada arquivo é um hash do próprio item, então coletar a mesma notícia duas vezes só sobrescreve o mesmo arquivo.

Três Workers e um banco D1. A coleta só escreve no R2, o processamento faz o resto e a API só lê.
  • Coleta. Um Worker com crons lê os feeds RSS de hora em hora. Para o histórico que o RSS não mostra, ele anda pelos sitemaps dos sites.
  • Processamento. Cada arquivo novo no R2 vira uma mensagem numa fila. Outro Worker limpa o texto, deduplica no D1 e chama o Clef, um modelo de decisão do Workers AI que devolve uma probabilidade para cada tema e sentimento.
  • Mesma pauta. A cada 10 minutos as notícias viram vetores no bge-m3 e vão para o Vectorize. Vizinhos muito próximos de fontes diferentes contam como a mesma matéria.
  • Serve. De hora em hora um cron recalcula no D1 as tabelas que o dashboard lê. Uma API em Hono entrega essas tabelas e o front é React, com gráficos em visx.

Até setembro o processamento era Python na minha máquina. Em outubro migrei tudo para os Workers, com testes mostrando que o resultado batia com o do Python. O Python ficou como laboratório para calibrar limiares.

O que ainda falta

  • Não há gabarito humano. Os rótulos de sentimento foram comparados só com juízes LLM.
  • A troca de classificador em setembro quebrou a série de sentimento, e a reclassificação do histórico ainda não rodou.
  • 98 mil notícias que vieram de sitemap têm só o slug da URL como título, sem acento e sem resumo.

Playground

Uma cópia das regras de limpeza do Worker roda aqui no navegador: quais bancos a notícia cita, se ela é do setor e qual a chave de deduplicação.

O que a silver extrai de uma notícia

Escolha um caso ou edite o texto. As regras são as mesmas do worker, rodando no seu navegador.

dedup_key
infomoney.com.br/minhas-financas/varejo-cresce-4-no-dia-das-criancas-diz-getnet-transacoes-via-pix-lideraram-alta
bancos
nenhum
termos do setor
pix
entra no setor?
sim

Nenhum banco citado, mas "pix" é termo do setor. Os parâmetros utm somem da chave.

O Clef devolve uma probabilidade por sentimento, e um limiar decide quando uma notícia “neutra” vira positiva ou crítica. Mexa no limiar e compare com o Codex, o motor anterior, nas 129 notícias em que os dois juízes LLM concordaram.

Quando o "neutro" do Clef vira polo

129 notícias em que os dois juízes concordaram. Cada ponto é uma notícia; a posição é a probabilidade que o clef-flash deu ao polo mais provável. Arraste o limiar.

0,30
71%polo certo · Codex 98%
8%neutras viradas polo · Codex 35%
0,81macro-F1 · Codex 0,78
  • rótulo final crítico
  • rótulo final positivo
  • rótulo final neutro
  • argmax já era polo
0,000,200,400,60≥ 0,8juízes: polar52 notíciasjuízes: neutra77 notícias

Dados do teste de polaridade de 10/10/2026: 200 notícias do setor, juízes Haiku e Sonnet às cegas, e as respostas cruas do clef-flash guardadas no bake-off. Com o limiar desligado o Clef acerta o polo em 42%. Nenhum motor, em nenhum limiar, inverteu positivo e crítico.