StockBot
De uma exploração em um chat a um bot de alertas de opções rodando sozinho e de graça — e a descobrir que montar o agente era a parte fácil: o difícil é ele acertar.
Ver produto →Resumo rápido
- Função
- Builder solo
- Período
- 9 de setembro → outubro de 2026
- Stack técnico
- Exploração em chat no Claude → implementação e deploy no Claude Code, sobre Python, Alpaca, Telegram e GitHub Actions → avaliação em sombra das recomendações
- Produto
- t.me/CelsoStockBot
O problema
IONQ é uma ação que acompanho normalmente. A ideia do StockBot não foi montar um sistema de trading algorítmico ambicioso desde o primeiro dia, mas algo bem menor: parar de precisar olhar o gráfico o dia todo para não perder uma entrada, e em vez disso receber um aviso pelo Telegram quando as condições técnicas (RSI, MACD, EMA) apontarem para uma oportunidade de compra de opções (calls ou puts).
Escolhi começar com uma única ação — a que já acompanho — em vez de montar algo genérico para qualquer ticker desde o início. A ideia era validar o conceito completo (sinal → contrato sugerido → aviso → acompanhamento da posição) sobre um caso concreto antes de pensar em escalar para mais símbolos.
A construção
Exploração (9 de setembro) — chat do Claude
Toda a arquitetura foi pensada e escrita em uma conversa de chat com o Claude (claude.ai), sem executar nada ainda: as regras de análise técnica, a integração com a Alpaca para dados e cadeia de opções, o formato dos alertas do Telegram, e o plano de deploy no GitHub Actions. O código completo saiu de uma vez, mas um chat não tem como instalar dependências, chamar uma API real, nem dizer se algo realmente funciona — ficou como um design completo, mas não validado.
Implementação e deploy (10 de setembro) — Claude Code
É aqui que o projeto passou de “código que parece pronto” para “bot rodando de verdade”. O repositório foi montado, tudo foi testado com credenciais reais, os bugs que só aparecem na execução foram debugados, e o projeto foi para produção.
- Python + pandas — motor de indicadores técnicos (RSI, MACD, EMA, ATR) calculado manualmente, sem
pandas_ta, porque essa biblioteca ainda não suporta a versão do Python usada localmente. - Alpaca Markets API — dados de candles intradiários e cadeia de opções, no plano Basic gratuito (feed IEX para ações, feed indicativo para opções) com uma conta paper usada só para leitura de dados.
- Telegram Bot API — canal de alertas de entrada/saída, e depois também leitura de mensagens recebidas para saber se mais alguém escreve para o bot.
- GitHub + GitHub Actions — repositório, controle de versão, e a tentativa inicial de host gratuito para rodar o bot a cada 15 minutos via cron.
- cron-job.org — disparador externo que chama a API do GitHub para forçar a execução do workflow, adicionado quando o cron nativo do Actions não funcionou (ver Escalonamento).
Avaliação em sombra e primeiras calibrações (setembro → outubro)
Com o bot rodando, deixei ele recomendando sem colocar dinheiro real: os alertas foram avaliados “em sombra”, como se eu os tivesse seguido em uma simulação. A primeira coisa que apareceu foi que a regra quase não disparava: um backtest de 10 dias sobre os 4 símbolos mostrou zero sinais, porque exigia que o RSI extremo, o cruzamento do MACD e a posição do preço em relação à sua EMA coincidissem na mesma vela de 15 minutos — condições que, na prática, acontecem em momentos diferentes do mesmo movimento. Tirei o filtro de EMA e passei o RSI extremo para uma janela das últimas 6 velas, e aí sim começaram a aparecer sinais.
O problema é que “dispara mais” não é o mesmo que “recomenda bem”. Ao avaliar em sombra o que ele realmente recomendava, as recomendações se mostraram bastante ruins: recomendou comprar umas calls e justo o mercado caiu, e na simulação perdeu-se bastante dinheiro. A calibração tinha sido feita no olho, ajustando contra poucos dias de dados e com a única régua de “que gere sinais” — não de “que esses sinais sirvam”.
Escalonamento
- De “cron nativo do GitHub Actions” para “disparador externo via HTTP”: o
scheduledo Actions nunca disparou sozinho, nem uma vez, em mais de 2,5 horas — com a configuração 100% correta (branch, permissões, sintaxe do cron, workflow ativo). As mitigações conhecidas foram testadas (deslocar os minutos do cron para evitar os picos de carga em :00/:15/:30/:45, e forçar o re-registro desabilitando e reabilitando o workflow) e nenhuma resolveu. A solução foi tirar o GitHub Actions do papel de “scheduler” e deixá-lo só como executor: agora um serviço externo gratuito (cron-job.org) chama a cada 15 minutos o endpoint deworkflow_dispatchda API do GitHub para disparar a execução. - De “o agente funciona” para “o agente acerta”: a quebra mais importante não foi de infraestrutura, mas de qualidade. O bot rodava sem erros, mandava alertas e respeitava os filtros, mas as recomendações eram ruins e estavam mal calibradas. Ajustar limiares olhando poucos dias de dados não basta para saber se uma regra é boa; é preciso construir evals para testá-la em laboratório (backtests sobre um histórico amplo, com métricas de resultado e não só de quantidade de sinais) e observabilidade em produção para medir a qualidade dos outputs depois de implantado (o que foi recomendado, o que aconteceu depois, quanto se teria ganhado ou perdido).
Resultados
| Etapa | Período | Resultado | Custo |
|---|---|---|---|
| Exploração | 9-set-2026 | Código e arquitetura completos, nunca executados | $0 |
| Implementação e deploy | 10-set-2026 | Bot em produção, respondendo com informação real (sinais de AT, status do mercado) | $0 (planos gratuitos: Alpaca + GitHub Actions + cron-job.org) |
| Avaliação em sombra | set → out-2026 | As recomendações se mostraram ruins: recomendou comprar calls pouco antes de uma queda do mercado e a simulação perdeu bastante dinheiro. Regra mal calibrada | $0 em infraestrutura; a perda foi apenas simulada, sem dinheiro real |
Não há um valor consolidado da perda na simulação, nem um registro sistemático de cada recomendação contra o que aconteceu depois — justamente o que ainda falta construir. Até que existam evals e observabilidade, não há como dizer com dados quão boa ou ruim é a regra além destes casos pontuais.
Aprendizados
- Montar o agente é a parte mais fácil; o complexo é garantir a qualidade da resposta. No StockBot, ter algo rodando, conectado a dados reais e mandando alertas levou um par de dias. Saber se o que ele recomenda é bom eu ainda não tenho resolvido: as recomendações em sombra foram ruins e a regra estava mal calibrada. Antes de confiar em um agente são necessários evals para testá-lo em laboratório e observabilidade em produção para medir a qualidade dos seus outputs ao longo do tempo.
- Vale mais testar e ir descobrindo os bloqueios e suas soluções conforme se avança, em vez de tentar prevê-los todos de antemão. Nem o problema das credenciais nem o do scheduler do GitHub Actions podiam ter sido antecipados na fase de design — só apareceram ao executar, e foram resolvidos no processo.
- Um chat de LLM sem execução real pode produzir código que parece pronto mas nunca rodou. Toda a exploração no claude.ai gerou um projeto completo e coerente, mas a única forma de saber se realmente funcionava era rodá-lo — algo que aquele ambiente não permite.
- Verificar credenciais com uma chamada real à API, não com a ausência de erros. Um secret mal carregado pode retornar “sem exceção” e mesmo assim estar apontando para um token ou chat errado — é preciso confirmar com uma resposta concreta (
getMe,/v2/account) antes de presumir que algo ficou bem configurado. - Não presumir que uma peça de infraestrutura conhecida (o cron do GitHub Actions) vai funcionar como documentado. Quando falhou sem causa identificável, ter um plano B simples (um disparador HTTP externo) resolveu mais rápido do que insistir na peça quebrada.