anti-gambling-trader-tw
Free open-source investment anti-fraud, trading statistics and automated trading program tools: default PaperBroker, provides 14 broker/exchange options; trade record analysis runs locally.
AI translation
Track your income, expenses, investments and generate financial reports
AI summary · website content
FinanceHTML · JavaScriptGitHub @Le3DevOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗App pessoal para lançar o salário, separar o que fica comigo e o que vai para investir, controlar revendas e acompanhar o patrimônio todo dia.
public/index.html — o app inteiro (uma página).public/relatorio.js — os relatórios em PDF (semana/mês e "Meus gastos"), desenhados no aparelho com o jsPDF.public/extrato.js — leitura do extrato do Itaú em PDF, no próprio aparelho. Veja Controle de gastos.api/ — funções da Vercel:
login — entra com a senha (APP_PASSWORD) e guarda a sessão por um ano;estado / escrever — leem e gravam os dados num arquivo JSON privado do Vercel Blob. Ao gravar um gasto, escrever também confere o aviso de 80%/100% do mês (api/_alertasGastos.js);importar — restaura um backup;mercado — busca dólar PTAX, CDI, Selic e IPCA no Banco Central e guarda o fechamento diário dos índices de mercado. Roda sozinho todo dia útil às 18h (cron em vercel.json) e também quando o app abre com os dados velhos;indices — cotação dos índices de mercado na hora (gráficos, resumo do dia e destaques da semana). Veja Índices de mercado.Nenhum dado pessoal fica neste repositório: tudo mora no Blob privado da conta Vercel.
APP_PASSWORD com a senha do app.Opcionais: APP_SECRET (chave da sessão; sem ela, é derivada da senha) e CRON_SECRET
(protege a chamada do cron).
Para conferir a configuração: https://SEU-DOMINIO/api/estado?diag=1.
Todo dia útil, junto com a atualização do dólar e do CDI, o app grava uma cópia dos dados em
caixa/backups/AAAA-MM.json no Blob (uma por mês, com o último estado do mês). Para restaurar,
baixe o arquivo no painel da Vercel (Storage → Blob) e use Ajustes → Importar backup.
Na aba Mês, o card de índices mostra o gráfico de cada índice, a variação do dia e a do período.
| Índice | O que mede |
|---|---|
| Ibovespa | Principal índice da B3: as ações mais negociadas da bolsa brasileira, com peso pelo valor de mercado. A carteira é revista a cada 4 meses. |
| IFIX | Os fundos imobiliários (FIIs) mais negociados da B3. |
| S&P 500 | As 500 maiores empresas dos EUA, com peso pelo valor de mercado. |
| Nasdaq (Composite) | Todas as ações listadas na Nasdaq, com forte peso de tecnologia. |
| Dow Jones | 30 grandes empresas americanas, com peso pelo preço da ação (não pelo tamanho da empresa). |
| Nikkei 225 | As 225 principais empresas da Bolsa de Tóquio, com peso pelo preço da ação. |
Períodos: 1D (pregão atual, pontos a cada 5 min), 5D (5 pregões, a cada 15 min), 1M, 6M,
YTD (desde 1º de janeiro), 1A, 5A (um ponto por semana) e MAX (um ponto por mês). As datas são
sempre a data local da bolsa (Tóquio está 12h à frente de Brasília).
Atualização ao vivo: os gráficos são buscados na hora, quando o card abre ou o período muda. O servidor
guarda cada resposta por 60 s (1D, 5D e resumo), 5 min (1M) ou 15 min (demais períodos). Durante o
pregão o app atualiza sozinho a cada 60 s. Se a busca ao vivo falhar, o app usa os fechamentos diários que
o cron grava em mercado_hist e mostra o aviso de mercado.atual.indicesErro. Com o pregão aberto,
o cron não grava a barra do dia (ainda não é fechamento); ela entra na passada seguinte.
Destaques da semana: as ações do Ibovespa que mais caíram e mais subiram na semana (até 10 de cada).
A semana vai da segunda até a última cotação e é comparada com o fechamento do pregão anterior à
segunda (normalmente a sexta). No sábado e no domingo aparece a semana que acabou. Na segunda antes da
abertura (sem cotação na semana) aparece a semana anterior, fechada (fechada: true).
Todos exigem login (cookie da sessão). Sem login: 401 { "erro": "login" }. Respostas com
cache-control: private, max-age=30.
GET /api/indices?id=<id>&periodo=<periodo>: gráfico de um índice.
id: ibovespa | ifix | sp500 | nasdaq | dowjones | nikkeiperiodo: 1D | 5D | 1M | 6M | YTD | 1A | 5A | MAX{
"id": "ibovespa", "nome": "Ibovespa", "moeda": "BRL", "periodo": "1D",
"valor": 165405.4, "horario": "2026-11-03T15:50:30.000Z", "pregaoAberto": true,
"fechamentoAnterior": 167921.8, "intradiario": true,
"pontos": [{ "t": 1793710800000, "data": "2026-11-03", "valor": 167917.3 }],
"resumo": { "abertura": 167917.3, "alta": 168005.45, "baixa": 164446.53, "alta52": 209714, "baixa52": 149979 },
"fonte": "Yahoo Finance"
}
moeda: BRL | USD | JPY | null. horario: ISO (UTC) da última cotação.pontos: ordenados por t (epoch em ms). data é a data local da bolsa. intradiario é true em 1D e 5D (pontos com hora).resumo e fechamentoAnterior são sempre da sessão atual (ou da última, com a bolsa fechada). Os campos podem vir null.fonte: Yahoo Finance ou CNBC.400 { "erro": "..." } para id ou período inválido; 502 { "erro": "Não consegui buscar o <nome> agora. Tente de novo em alguns minutos." } quando todas as fontes falharam.GET /api/indices?lista=resumo: último valor e variação do dia de todos os índices.
{
"atualizadoEm": "2026-11-03T16:06:01.412Z",
"indices": [{ "id": "sp500", "nome": "S&P 500", "moeda": "USD", "valor": 7584.87,
"variacaoDia": 43.47, "variacaoDiaPct": 0.5764,
"horario": "2026-11-03T16:06:00.000Z", "pregaoAberto": true }],
"falhas": { "nikkei": "Não consegui buscar o Nikkei 225 agora. Tente de novo em alguns minutos." },
"fonte": "Yahoo Finance"
}
variacaoDia = valor − fechamento anterior; variacaoDiaPct em %. O índice que falhou sai de
indices e aparece em falhas.
GET /api/indices?lista=destaques-semana: maiores quedas e altas da semana entre as ações do Ibovespa.
{
"semana": { "de": "2026-11-02", "ate": "2026-11-03", "base": "2026-10-30" },
"fechada": false, "atualizadoEm": "...",
"quedas": [{ "codigo": "XXXX3", "nome": "...", "preco": 10.5, "variacaoSemana": -1.2,
"variacaoSemanaPct": -10.26, "participacao": 1.8 }],
"altas": [], "total": 84, "semDados": ["YYYY3"], "fonte": "..."
}
semana.base é o pregão usado como referência (fechamento anterior à segunda). Há até 10 ações em
quedas e 10 em altas. total é quantas ações entraram na conta, e semDados lista as que ficaram sem cotação.
Se não der para montar a lista, a resposta é 502 { "erro": "Não consegui montar os destaques da semana agora. Tente de novo em alguns minutos." }.
Campos gravados por /api/mercado em mercado.atual: indices (último valor e variação do dia de
cada índice, para o app usar sem a API ao vivo), indicesAtualizadoEm (ISO da última busca que deu certo)
e indicesErro (mensagem da última falha, ou null quando todos vieram). O retorno de /api/mercado
traz também falhasIndices: { <id>: mensagem }.
Na aba Para mim, os gastos do mês são comparados com o valor que fica com você no mês (Ajustes,
config.main.paraMim), chamado aqui de meta. O mês é o mês da data do gasto, no
horário de Brasília. Gastos fixos e gastos importados do extrato contam como qualquer outro gasto.
/api/escrever), o servidor recalcula o mês atual. Se chegou a
80% ou passou de 100%, manda uma notificação para os aparelhos inscritos. Tocar nela abre a aba Para mim
(/?aba=mim).
enviados de caixa/push.json com a chave
gastos:AAAA-MM:80 ou gastos:AAAA-MM:100. Apagar um gasto e lançar de novo não repete o aviso.fixos (descrição, categoria e valor de cada conta que se repete todo mês).tipo: 'gasto', fixoId) com data do dia 1º do mês, e já desconta da meta desde o começo do mês.fixo-<id do fixo>-<AAAA-MM>. Lançar de novo, por outro aparelho ou outra aba, grava
o mesmo documento, então o fixo não duplica.public/extrato.js). Ele não é enviado para o servidor nem guardado. Só as linhas que você confirma viram gastos.regras e usa essa categoria nas próximas importações.chaveExtrato), e o gasto é gravado
com um id que sai dessa chave. Importar o mesmo extrato de novo, ou um extrato com dias repetidos, não duplica nada.O mês atual até hoje é comparado com o mesmo ponto do mês passado (até o mesmo dia) e com a média dos 3 meses anteriores, no total e por categoria.
O gráfico de barras dos 6 meses fica no card de gastos (ver "Ver gastos de outros meses"), e não mais no card Mês a mês. O card Mês a mês continua sempre sobre o mês atual, e o relatório em PDF não mudou.
O relatório em PDF "Meus gastos" é gerado no aparelho (window.caixaRelatorioGastosPDF(d) em
public/relatorio.js, que devolve um Blob) e traz:
Campos sem valor (null) aparecem como "—".
Dados que a tela passa para o relatório:
{
titulo: 'Meus gastos · nov. de 2026', ate: '2026-11-03', meta: 1100,
meses: [{ mes: '2026-06', nome: 'jun. de 2026', total, fixos, variaveis, sobra /* meta − total */, porCat: [{ id, nome, v }] }], // 6 meses, do mais antigo ao atual
atual: { mes, nome, total, ateDia, mesmoPontoMesPassado /* ou null */, mediaAnteriores3 /* ou null */ },
categorias: [{ id, nome, atual, media3, dif }],
maiores: [{ data, descricao, categoria, valor }],
destaques: ['texto curto']
}
| Onde | O que guarda |
|---|---|
movimentos | Gastos, entradas e ajustes: { tipo: 'gasto' | 'entrada' | 'ajuste', valor (positivo), data 'AAAA-MM-DD', categoria, descricao }. Campos novos: fixoId (gasto lançado por um fixo), origem: 'extrato' e chaveExtrato (gasto importado do extrato). |
fixos | Os gastos fixos do mês e os meses pulados de cada um. |
regras | As regras de categoria aprendidas na importação do extrato (trecho da descrição → categoria). |
caixa/push.json → enviados | As chaves gastos:AAAA-MM:80 e gastos:AAAA-MM:100 dos avisos já enviados. |
Categorias: uber (Uber e 99), ifood (iFood), restaurante, mercado, transporte, combustivel
(Combustível), farmacia (Farmácia), compras, assinaturas, viagem, lazer e outro.
Índices buscados sob demanda, não pelo cron
/api/indices busca na fonte quando o app pede. O cron continua gravando os fechamentos diários em mercado_hist.Yahoo Finance + CNBC como fontes; Stooq removido
IFIX.SA só traz o intradiário).query2), e a CNBC entra como reserva (.BVSP, .IFIX, .SPX, .IXIC, .DJI, .N225). Quando o Yahoo não cobre o período pedido, a CNBC é usada no lugar. Tudo passa pelo módulo api/_indices.js, que converte os formatos das duas fontes para o modelo do app.Composição do Ibovespa pela B3, com cache de 24h
participacao). A carteira muda só a cada 4 meses.Cache em memória, não na CDN
Map dentro da função (60 s a 15 min, conforme o período) e cache-control: private para o navegador. Se a fonte falhar, o servidor devolve o último dado bom com até 6h.Extrato em PDF lido no navegador
public/extrato.js). Para o servidor vão só as linhas confirmadas, já como movimentos, pelo /api/escrever de sempre.public/extrato.js precisa mudar. Cada pedido ao /api/escrever aceita até 100 operações, então importações maiores vão em mais de um pedido.Aviso de gastos disparado na gravação, não no cron
/api/escrever recalcula o mês atual se o pedido mexeu em movimentos (api/_alertasGastos.js, só cálculo). Se a faixa mudou, ele envia pelo api/_push.js e marca a chave em enviados. Tudo fica num try/catch: erro na notificação não muda a resposta.caixa/push.json. Pedidos que não mexem em gastos (como mudar a meta em Ajustes) e o que não passa pelo /api/escrever (importar backup) só disparam o aviso no próximo gasto gravado. Duas gravações no mesmo instante podem mandar o aviso duas vezes, mas a notificação tem a mesma tag e o celular mostra uma só.Ids determinísticos para gastos fixos e importação
fixo-<id>-<AAAA-MM>, e o gasto importado usa um id que sai da chave da linha do extrato (chaveExtrato).