O Beancount (uma ferramenta de contabilidade de partidas dobradas em texto simples) e o Fava (sua interface web) são altamente extensíveis e scriptáveis. Seu design permite automatizar tarefas financeiras, gerar relatórios personalizados e configurar alertas escrevendo scripts Python. Nas palavras de um usuário: "Gosto muito de ter meus dados em um formato tão conveniente, e gosto de poder automatizar as coisas à vontade. Não existe API como um arquivo no seu disco; é fácil de integrar." Este guia percorrerá a criação de fluxos de trabalho scriptáveis — desde automações amigáveis para iniciantes até plugins avançados do Fava.
Explore um razão de exemplo ao vivo:
Comece com a linha de comando bea
Antes de escrever qualquer Python, verifique se o bea já faz o trabalho. Ele valida o razão, executa consultas BQL, produz os quatro relatórios financeiros e importa extratos bancários, e o --json global transforma cada um deles em um envelope analisável que seu shell pode canalizar para o jq. Seus códigos de saída são o contrato no qual um trabalho agendado se baseia, então o cron ou a CI não precisam de nenhum script carregador. Veja automatize a contabilidade com bea para resolução de alvos, envelope e ramificação por código de saída, e volte aqui quando precisar de um cálculo personalizado que a CLI não expõe.
Primeiros Passos: Executando Beancount como Script Python
Para os scripts Python personalizados abaixo, instale as bibliotecas de script (pip install beancount beanquery beangulp). Os fluxos de trabalho do comando bea usam o motor gerenciado; siga o guia rápido da CLI para instalá-lo. Como o Beancount é escrito em Python, você pode usá-lo como uma biblioteca em seus próprios scripts. Os scripts abaixo foram executados com Beancount 3.2.3, beanquery 0.2.0 e beangulp 0.2.0. A abordagem geral é:
-
Carregue seu razão Beancount: Use o loader do Beancount para analisar o arquivo
.beancountem objetos Python. Por exemplo:from beancount import loader entries, errors, options = loader.load_file("myledger.beancount") if errors: for error in errors: print(error) raise SystemExit(1)O loader retorna entradas e erros juntos. Um arquivo desbalanceado ou inválido ainda retorna entradas, então verifique
errorse pare antes de confiar nos dados. Todas as suas contas, transações e saldos agora estão acessíveis no código. -
Aproveite a Beancount Query Language (BQL): Em vez de iterar manualmente, você pode executar consultas do tipo SQL sobre os dados. As consultas residem no pacote separado
beanquery. Não existe um módulobeancount.queryno Beancount 3.2.3. Por exemplo, para obter o total de despesas por mês, conecte as entradas carregadas e execute a consulta diretamente:import beanquery conn = beanquery.connect("beancount:", entries=entries, errors=errors, options=options) cur = conn.execute( "SELECT year, month, sum(position) WHERE account ~ 'Expenses' GROUP BY year, month" ) for row in cur.fetchall(): print(row)Isso usa o beanquery para agregar dados. É o mesmo motor por trás de
bea query, mas aqui você o chama em um script. Isso evita invocar um comando externo em um loop. -
Configure uma estrutura de projeto: Organize seus scripts junto ao seu razão. Um layout comum é ter diretórios para importers (para buscar/analisar dados externos), reports ou queries (para scripts de análise) e documents (para armazenar extratos baixados). Por exemplo, um usuário mantém:
importers/– scripts de importação Python personalizados (com testes),queries/– scripts para gerar relatórios (executáveis viapython3 queries/...),documents/– CSVs/PDFs bancários baixados organizados por conta.
Com essa configuração, você pode executar scripts manualmente (por exemplo, python3 queries/cash_flow.py) ou agendá-los (via cron ou um executor de tarefas) para automatizar seu fluxo de trabalho.
Automatizando Tarefas de Conciliação
Reconciliação significa garantir que seu razão corresponda aos registros externos (extratos bancários, faturas de cartão de crédito, etc.). O razão em texto simples do Beancount e sua API Python tornam possível automatizar grande parte desse processo.
Importando e Conciliando Transações (Iniciante)
Para iniciantes, a abordagem recomendada é usar importers do pacote separado beangulp. O Beancount 3 removeu o módulo de ingestão v2 e seu comando extract. Você escreve uma pequena classe Python que herda de beangulp.Importer para analisar um formato específico (CSV, OFX, PDF, etc.) e produzir transações. Registre-a em um pequeno script de ingestão e então execute-a através de bea ingest no motor gerenciado:
- Escreva um importer (uma classe Python com os métodos
identify(),account()eextract()) para o formato CSV do seu banco. - Adicione um script de ingestão que registra seus importers. O
bea ingestexecuta os comandosidentify,extractearchivedo script. Por exemplo, um fluxo de trabalho executaextractem todos os arquivos em~/Downloadse envia as transações para um arquivo temporário. - Revise manualmente e copie as transações do arquivo temporário para o seu razão principal, então execute
bea checkpara garantir que os saldos reconciliem.
Um exemplo mínimo: um statement.csv com colunas date,description,amount, analisado por este importer (checking_importer.py):
import csv
import datetime
from beancount.core import data
from beancount.core.amount import Amount
from beancount.core.number import D
import beangulp
class CheckingImporter(beangulp.Importer):
def identify(self, filepath: str) -> bool:
return filepath.endswith("statement.csv")
def account(self, filepath: str) -> str:
return "Assets:Bank:Checking"
def extract(self, filepath: str, existing):
entries = []
with open(filepath, newline="") as f:
for row in csv.DictReader(f):
date = datetime.date.fromisoformat(row["date"])
amount = Amount(D(row["amount"]), "USD")
meta = data.new_metadata(filepath, 0)
entries.append(
data.Transaction(
meta, date, "*", None, row["description"],
data.EMPTY_SET, data.EMPTY_SET, [
data.Posting("Expenses:Food:Groceries", amount,
None, None, None, None),
data.Posting("Assets:Bank:Checking",
Amount(-amount.number, "USD"),
None, None, None, None),
]))
return entriesO script de ingestão (ingest.py) o conecta:
from checking_importer import CheckingImporter
from beangulp import Ingest
ingest = Ingest([CheckingImporter()])
if __name__ == "__main__":
ingest()Execute-o contra um arquivo baixado. Nenhuma credencial é necessária para um CSV local. Instale a biblioteca libmagic do sistema primeiro. O comando de habilitação de uso único baixa o Beangulp para o motor gerenciado:
bea engine enable beangulp
bea ingest identify --config ingest.py statement.csv
bea ingest extract --config ingest.py statement.csv -o new.beancountO identify reporta checking_importer.CheckingImporter para o arquivo. O extract grava as transações no formato Beancount:
2024-01-08 * "Grocery Store"
Expenses:Food:Groceries 120.00 USD
Assets:Bank:Checking -120.00 USDRevise o new.beancount, copie as entradas para o seu razão principal e execute bea check.
Você não precisa escrever um importer para converter um único extrato. Cole o arquivo no conversor de CSV para Beancount, ou use o OFX & QIF para Beancount para downloads .ofx, .qfx e .qif. Ambos rodam inteiramente no seu navegador, então o extrato nunca sai da sua máquina.
Embora esse processo ainda envolva uma etapa de revisão, grande parte do trabalho braçal de analisar e formatar entradas é automatizado. Os scripts de importer também podem atribuir categorias automaticamente e até definir asserções de saldo (declarações de saldos esperados) para detectar discrepâncias. Por exemplo, após importar, você pode ter uma linha como 2025-04-30 balance Assets:Bank:Checking 1234.56 USD que afirma o saldo de fechamento. Quando você executa bea check, o Beancount verifica se todas essas asserções de saldo estão corretas e sinaliza quaisquer erros se as transações estiverem faltando ou duplicadas. Esta é uma boa prática: gerar automaticamente asserções de saldo para cada período de extrato para deixar o computador identificar diferenças não reconciliadas para você.
Scripts de Conciliação Personalizados (Intermediário)
Para mais controle, você pode escrever um script Python personalizado para comparar a lista de transações de um banco (CSV ou via API) com as entradas do seu razão:
- Leia os dados externos: Analise o arquivo CSV do banco usando o módulo
csvdo Python (ou Pandas). Normalize os dados em uma lista de transações, cada uma com data, valor e descrição. - Carregue as transações do razão: Use
loader.load_filecomo mostrado anteriormente para obter todas as entradas do razão. Filtre essa lista pela conta de interesse (por exemplo, sua conta corrente) e talvez pelo intervalo de datas do extrato. - Compare e encontre divergências:
- Para cada transação externa, verifique se existe uma entrada idêntica no razão (correspondência por data e valor, talvez descrição). Se não for encontrada, marque-a como "nova" e possivelmente emita-a como uma transação formatada em Beancount para você revisar.
- Inversamente, identifique quaisquer entradas do razão nessa conta que não apareçam na fonte externa – estas podem ser erros de digitação ou transações que ainda não foram compensadas pelo banco.
- Produza os resultados: Imprima um relatório ou crie um novo trecho
.beancountcom as transações ausentes.
Como exemplo, um script da comunidade chamado reconcile.py faz exatamente isso: dado um arquivo Beancount e um CSV de entrada, ele imprime uma lista de novas transações que devem ser importadas, bem como quaisquer lançamentos existentes no razão que não estejam na entrada (potencialmente um sinal de classificação incorreta). Com esse script, a reconciliação mensal pode ser tão simples quanto executá-lo e então anexar as transações sugeridas ao seu razão. Um usuário do Beancount observa que eles "fazem um processo de reconciliação em todas as contas a cada mês" e usam uma coleção crescente de código Python para eliminar grande parte do trabalho manual na importação e reconciliação de dados.
Dica: Durante a reconciliação, aproveite as ferramentas do Beancount para garantir precisão:
- Use asserções de saldo como mencionado, para ter verificações automatizadas dos saldos das contas.
- Use a diretiva
padse desejar, que pode inserir automaticamente entradas de balanceamento para pequenas diferenças de arredondamento (use com cautela). - Escreva testes unitários para seu importer ou lógica de reconciliação (o Beancount fornece auxiliares de teste). Por exemplo, um fluxo de trabalho envolveu pegar um CSV de amostra, escrever testes que falham com as transações esperadas, e então implementar o importer até que todos os testes passassem. Isso garante que seu script de importação funcione corretamente para vários casos.
Gerando Relatórios e Resumos Personalizados
Embora o Fava forneça muitos relatórios padrão (Demonstrativo de Resultados, Balanço Patrimonial, etc.), você pode criar relatórios personalizados usando scripts. Estes podem variar de saídas simples no console a arquivos formatados sofisticados ou gráficos.
Consultando Dados para Relatórios (Iniciante)
Em um nível básico, você pode usar a Beancount Query Language (BQL) para obter dados de resumo e imprimi-los ou salvá-los. Por exemplo:
-
Resumo de Fluxo de Caixa: Use uma consulta para calcular o fluxo de caixa líquido. "Fluxo de caixa" pode ser definido como a variação do saldo de certas contas ao longo de um período. Usando BQL, você poderia fazer:
SELECT year, month, sum(position) WHERE account ~ 'Income' OR account ~ 'Expenses' GROUP BY year, monthIsso soma todos os lançamentos de receita e despesa por mês. Filtre com
~e uma expressão regular:LIKEé um erro de sintaxe no beanquery 0.2.0. Os lançamentos carregamposition, nãoamount. Cada linha contém um Inventory, então cada moeda é listada separadamente em vez de ser convertida. A receita chega negativa e as despesas positivas. Você poderia executar isso através debea queryou via a API Python do beanquery mostrada anteriormente, e então formatar o resultado. -
Relatório de Gastos por Categoria: Consulte o total de despesas por categoria:
SELECT account, sum(position) WHERE account ~ 'Expenses' GROUP BY account ORDER BY sum(position) ASCIsso produz uma tabela de despesas por categoria. Cada total é um Inventory em sua moeda original. Não envolva o agregado em
round(): não existe uma funçãoround(inventory, int), entãoround(sum(position), 2)falha ao compilar. Você pode executar várias consultas em um script e emitir os resultados como texto, CSV ou até JSON para processamento posterior.
Um usuário considerou "trivial" analisar dados financeiros com o Fava ou com scripts, citando que usa um script Python para extrair dados do Beancount via a Query Language e então colocá-los em um DataFrame do Pandas para preparar um relatório personalizado. Por exemplo, você pode buscar totais mensais com uma consulta e então usar Pandas/Matplotlib para traçar um gráfico de fluxo de caixa ao longo do tempo. A combinação de BQL e bibliotecas de ciência de dados permite que você construa relatórios além do que o Fava oferece por padrão.
Relatórios Avançados (Gráficos, Desempenho, etc.)
Para necessidades mais avançadas, seus scripts podem calcular métricas como desempenho de investimentos ou criar saídas visuais:
-
Desempenho de Investimentos (IRR/XIRR): Como seu razão contém todos os fluxos de caixa (compras, vendas, dividendos), você pode calcular as taxas de retorno do portfólio. Por exemplo, você poderia escrever um script que filtra transações das suas contas de investimento e então calcula a Taxa Interna de Retorno. Existem bibliotecas (ou fórmulas) para calcular a TIR dados os dados de fluxo de caixa. Algumas extensões do Fava desenvolvidas pela comunidade (como PortfolioSummary ou fava_investor) fazem exatamente isso, calculando TIR e outras métricas para portfólios de investimento. Como script, você poderia usar uma função de TIR (do NumPy ou a sua própria) sobre a série de aportes/resgates mais o valor final.
-
Métricas Multiperíodo ou Personalizadas: Quer um relatório da sua taxa de poupança (razão entre poupança e receita) a cada mês? Um script Python pode carregar o razão, somar todas as contas de Receita e todas as contas de Despesa, então calcular poupança = receita - despesas e a porcentagem. Isso poderia gerar uma bela tabela ou até um relatório HTML/Markdown para seus registros.
-
Visualização: Você pode gerar gráficos fora do Fava. Por exemplo, use
matplotliboualtairem um script para criar um gráfico de patrimônio líquido ao longo do tempo, usando dados do razão. Como o razão tem todos os saldos históricos (ou você pode acumulá-los iterando as entradas), você pode produzir gráficos de séries temporais. Salve esses gráficos como imagens ou HTML interativo. (Se você preferir visuais dentro do aplicativo, veja a seção de extensões do Fava abaixo para adicionar gráficos dentro do Fava.)
Opções de Saída: Decida como entregar o relatório:
- Para análise pontual, imprimir na tela ou salvar em um arquivo CSV/Excel pode ser suficiente.
- Para dashboards, considere gerar um arquivo HTML com os dados (possivelmente usando uma biblioteca de templates como Jinja2 ou até apenas escrevendo Markdown) que você possa abrir em um navegador.
- Você também pode integrar com Jupyter Notebooks para um ambiente de relatórios interativo, embora isso seja mais para exploração do que para automação.
Acionando Alertas a Partir do Seu Livro-Razão
Outro uso poderoso de fluxos de trabalho scriptáveis é configurar alertas com base em condições nos seus dados financeiros. Como seu razão é atualizado regularmente (e pode incluir itens com data futura, como contas a pagar ou orçamentos), você pode escaneá-lo com um script e ser notificado de eventos importantes.
Avisos de Saldo Baixo em Contas
Para evitar cheques sem fundos ou manter um saldo mínimo, você pode querer um alerta se alguma conta (por exemplo, corrente ou poupança) cair abaixo de um limite. Veja como implementar isso:
-
Determine os saldos atuais: Depois de carregar
entriesvia o loader, calcule o saldo mais recente das contas de interesse. Você pode fazer isso agregando lançamentos ou usando uma consulta. Por exemplo, use uma consulta BQL para o saldo de uma conta específica:SELECT sum(position) WHERE account = 'Assets:Bank:Checking'Isso retorna o saldo atual dessa conta (soma de todos os seus lançamentos). Alternativamente, use as funções internas do Beancount para construir um balanço patrimonial. Por exemplo:
from beancount.core import realization tree = realization.realize(entries) acct = realization.get_or_create(tree, "Assets:Bank:Checking") balance = acct.balance # an Inventory of commoditiesPasse apenas as entradas: o segundo parâmetro é
min_accounts, não o mapa de opções. Então extraia o valor numérico (por exemplo,balance.get_currency_units('USD')retorna o valor Decimal em USD). Como um agregado de consulta, o saldo mantém cada moeda separadamente. No entanto, usar a consulta é mais simples para a maioria dos casos. -
Verifique o limite: Compare o saldo com seu limite predefinido. Se estiver abaixo, dispare um alerta.
-
Dispare a notificação: Isso pode ser tão simples quanto imprimir um aviso no console, mas para alertas reais você pode enviar um e-mail ou notificação push. Você pode integrar com e-mail (via
smtplib) ou um serviço como IFTTT ou a API de webhook do Slack para enviar o alerta. Por exemplo:if balance < 1000: send_email("Low balance alert", f"Account XYZ balance is {balance}")(Implemente
send_emailcom os detalhes do seu servidor de e-mail.)
Ao executar esse script diariamente (via um trabalho cron ou o Agendador de Tarefas do Windows), você receberá avisos proativos. Como ele usa o razão, pode considerar todas as transações, incluindo as que você acabou de adicionar.
Prazos de Pagamento Próximos
Se você usa o Beancount para acompanhar contas ou prazos, pode marcar pagamentos futuros e ter scripts que o lembrem. Duas formas de representar obrigações futuras no Beancount:
-
Eventos: O Beancount suporta uma diretiva
eventpara notas datadas arbitrárias. Por exemplo:2025-05-10 event "BillDue" "Mortgage payment due"Isso não afeta os saldos, mas registra uma data com um rótulo. Um script pode escanear
entriesem busca de entradasEventondeEvent.type == "BillDue"(ou qualquer tipo personalizado que você escolher) e verificar se a data está dentro, digamos, dos próximos 7 dias a partir de hoje. Se sim, dispare um alerta (e-mail, notificação ou até um popup). -
Transações Futuras: Algumas pessoas inserem transações com data futura (pós-datadas) para coisas como pagamentos agendados. Estas não aparecerão nos saldos até a data passar (a menos que você execute relatórios com datas futuras). Um script pode procurar transações datadas no futuro próximo e listá-las.
Usando isso, você poderia criar um script de "lembrete" que, quando executado, emite uma lista de tarefas ou contas a vencer em breve. Integre com uma API como Google Calendar ou um gerenciador de tarefas se quiser criar lembretes automaticamente lá.
Detecção de Anomalias
Além de limites ou datas conhecidos, você pode programar alertas personalizados para padrões incomuns. Por exemplo, se uma despesa normalmente mensal não ocorreu (talvez você tenha esquecido de pagar uma conta), ou se os gastos de uma categoria estão anormalmente altos neste mês, seu script pode sinalizá-lo. Isso normalmente envolve consultar dados recentes e comparar com o histórico (o que pode ser um tópico avançado – possivelmente empregando estatística ou ML).
Na prática, muitos usuários dependem da reconciliação para detectar anomalias (transações inesperadas). Se você recebe notificações bancárias (como e-mails para cada transação), você pode analisá-las com um script e adicioná-las automaticamente ao Beancount, ou pelo menos verificar se estão registradas. Um entusiasta até configurou seu banco para enviar e-mails de alerta de transação, com o plano de analisá-los e anexá-los ao razão automaticamente. Esse tipo de alerta orientado a eventos pode garantir que nenhuma transação fique sem registro.
Estendendo o Fava com Plugins e Visualizações Personalizados
O Fava já é scriptável através de seu sistema de extensões. Se você quiser que sua automação ou relatórios se integrem diretamente à interface web, você pode escrever uma extensão do Fava (também chamada de plugin) em Python.
Como Funcionam as Extensões do Fava: Uma extensão é um módulo Python que define uma classe herdando de fava.ext.FavaExtensionBase. Você a registra no seu arquivo Beancount via uma opção personalizada. Por exemplo, se você tem um arquivo myextension.py com uma classe MyAlerts(FavaExtensionBase), você pode habilitá-la adicionando ao seu razão:
1970-01-01 custom "fava-extension" "myextension"Quando o Fava carregar, ele importará esse módulo e inicializará sua classe MyAlerts.
As extensões podem fazer várias coisas:
- Hooks: Elas podem se conectar a eventos no ciclo de vida do Fava. Por exemplo,
after_load_file()é chamado após o razão ser carregado. Você poderia usar isso para executar verificações ou pré-calcular dados. Se você quisesse implementar a verificação de saldo baixo dentro do Fava,after_load_filepoderia iterar sobre os saldos das contas e talvez armazenar avisos (embora exibi-los na interface possa exigir um pouco mais de trabalho, como lançar um FavaAPIError ou usar Javascript para mostrar uma notificação). - Relatórios/Páginas Personalizados: Se sua classe de extensão definir um atributo
report_title, o Fava adicionará uma nova página na barra lateral para ele. Você então fornece um template (HTML/Jinja2) para o conteúdo dessa página. É assim que você cria views totalmente novas, como um dashboard ou resumo que o Fava não tem por padrão. A extensão pode reunir quaisquer dados de que precise (você pode acessarself.ledger, que tem todas as entradas, saldos, etc.) e então renderizar o template.
Por exemplo, a extensão integrada portfolio_list no Fava adiciona uma página listando as posições do seu portfólio. Extensões da comunidade vão além:
- Dashboards: O plugin fava-dashboards permite definir gráficos e painéis personalizados (usando bibliotecas como Apache ECharts). Ele lê uma configuração YAML de consultas a executar, executa-as via Beancount e gera uma página de dashboard dinâmica no Fava. Em essência, ele une dados do Beancount e uma biblioteca de gráficos JavaScript para produzir visualizações interativas.
- Análise de portfólio: A extensão PortfolioSummary (contribuída por usuários) calcula resumos de investimento (agrupando contas, calculando TIR, etc.) e os exibe na interface do Fava.
- Revisão de transações: Outra extensão, fava-review, ajuda a revisar transações ao longo do tempo (por exemplo, para garantir que você não perdeu nenhum recibo).
Para criar uma extensão simples você mesmo, comece herdando de FavaExtensionBase. Por exemplo, uma extensão mínima que adiciona uma página poderia parecer com:
from fava.ext import FavaExtensionBase
class HelloReport(FavaExtensionBase):
report_title = "Hello World"
def __init__(self, ledger, config):
super().__init__(ledger, config)
# any initialization, perhaps parse config if provided
def after_load_file(self):
# (optional) run after ledger is loaded
print("Ledger loaded with", len(self.ledger.entries), "entries")Se você colocasse isso em hello.py e adicionasse custom "fava-extension" "hello" ao seu razão, o Fava mostraria uma nova página "Hello World" (você também precisaria de um arquivo de template HelloReport.html em uma subpasta templates para definir o conteúdo da página, a menos que a extensão use apenas hooks). O template pode usar dados que você anexa à classe da extensão. O Fava usa templates Jinja2, então você pode renderizar seus dados em uma tabela HTML ou gráfico nesse template.
Nota: O sistema de extensões do Fava é poderoso, mas considerado "instável" (sujeito a mudanças). Ele exige alguma familiaridade com desenvolvimento web (HTML/JS) se você estiver criando páginas personalizadas. Se seu objetivo é simplesmente executar scripts ou análises, pode ser mais fácil mantê-los como scripts externos. Use extensões do Fava quando quiser uma experiência personalizada dentro do aplicativo para seu fluxo de trabalho.
Integrando APIs e Dados de Terceiros
Uma das vantagens dos fluxos de trabalho scriptáveis é a capacidade de trazer dados externos. Aqui estão integrações comuns:
Para preços de avaliação hospedados, o Live Prices oferece includes gerenciados sem um script agendado de busca de preços. Escolha pares de ativos suportados e uma moeda de cotação no seletor. Os fluxos de trabalho locais baseados em arquivos abaixo continuam úteis para Beancount, Fava e relatórios reproduzíveis. Uma atualização gerenciada não cria um commit Git no seu razão.
-
Taxas de Câmbio e Commodities: O Beancount upstream não busca preços por conta própria, mas fornece uma diretiva
pricepara você fornecer as taxas. Você pode automatizar a busca desses preços. Por exemplo, um script pode consultar uma API (Yahoo Finance, Alpha Vantage, etc.) para obter a última taxa de câmbio ou cotação de ação e anexar uma entrada de preço ao seu razão:2025-04-30 price BTC 30000 USD 2025-04-30 price EUR 1.10 USDExistem ferramentas como
bea price, com suporte do Beanprice no motor gerenciado, que buscam cotações diárias e as emitem no formato Beancount. Você poderia habilitá-lo uma vez combea engine enable beanprice, então agendarbea price main.beancountpara rodar toda noite para atualizar um arquivo includeprices.beancount. Ou usar Python: por exemplo, com a bibliotecarequestspara chamar uma API. A documentação do Beancount sugere que, para ativos negociados publicamente, você pode "invocar algum código que baixará os preços e escreverá as diretivas para você." Em outras palavras, deixe um script fazer a busca e inserir as linhasprice, em vez de você fazer isso manualmente. -
Dados de Portfólio de Ações: Semelhante às taxas de câmbio, você pode integrar com APIs para buscar dados detalhados de ações ou dividendos. Por exemplo, a API do Yahoo Finance (ou bibliotecas da comunidade como
yfinance) pode recuperar dados históricos de um ticker. Um script poderia atualizar seu razão com o histórico mensal de preços de cada ação que você possui, permitindo relatórios históricos precisos do valor de mercado. Algumas extensões personalizadas (como fava_investor) até buscam dados de preços na hora para exibição, mas o mais simples é importar preços regularmente para o razão. -
APIs Bancárias (Open Banking/Plaid): Em vez de baixar CSVs, você pode usar APIs para buscar transações automaticamente. Serviços como Plaid agregam contas bancárias e permitem acesso programático às transações. Em uma configuração avançada, você poderia ter um script Python que usa a API do Plaid para puxar novas transações diariamente e salvá-las em um arquivo (ou importá-las diretamente para o razão). Um usuário avançado construiu um sistema onde o Plaid alimenta seu pipeline de importação, tornando seus livros quase automáticos. Ele observa que "nada impede você de se inscrever na API do Plaid e fazer o mesmo localmente" – ou seja, você pode escrever um script local para obter dados bancários, então usar sua lógica de importer do Beancount para analisá-los em entradas do razão. Algumas regiões têm APIs de open banking fornecidas por bancos; estas poderiam ser usadas de forma semelhante.
-
Outras APIs: Você pode integrar ferramentas de orçamento (exportando orçamentos planejados para comparar com os reais no Beancount), ou usar uma API de OCR para ler recibos e combiná-los automaticamente com transações. Como seus scripts têm acesso total ao ecossistema Python, você pode integrar tudo, desde serviços de e-mail (para enviar alertas) até Google Sheets (por exemplo, atualizar uma planilha com métricas financeiras mensais) até aplicativos de mensagens (enviar a si mesmo um relatório resumido via bot do Telegram).
Ao usar APIs de terceiros, lembre-se de proteger suas credenciais (use variáveis de ambiente ou arquivos de configuração para chaves de API) e tratar erros (problemas de rede, indisponibilidade da API) com elegância em seus scripts. Muitas vezes é prudente armazenar dados em cache (por exemplo, guardar as taxas de câmbio obtidas para não solicitar a mesma taxa histórica repetidamente).
Melhores Práticas para Scripts Modulares e Manteníveis
À medida que você constrói fluxos de trabalho scriptáveis, mantenha seu código organizado e robusto:
-
Modularidade: Divida diferentes preocupações em diferentes scripts ou módulos. Por exemplo, tenha scripts separados para "importação/reconciliação de dados" vs. "geração de relatórios" vs. "alertas". Você pode até criar um pequeno pacote Python para seu razão com módulos como
ledger_import.py,ledger_reports.py, etc. Isso torna cada parte mais fácil de entender e testar. -
Configuração: Evite valores codificados diretamente. Use um arquivo de configuração ou variáveis no topo do script para coisas como nomes de contas, limites, chaves de API, intervalos de datas, etc. Isso torna fácil ajustar sem editar o código profundamente. Por exemplo, defina
LOW_BALANCE_THRESHOLDS = {"Assets:Bank:Checking": 500, "Assets:Savings": 1000}no topo, e seu script de alerta pode percorrer esse dicionário. -
Testes: Trate sua automação financeira como código de missão crítica – porque é! Escreva testes para lógica complexa. O Beancount fornece alguns auxiliares de teste (usados internamente para testes de importer) que você pode aproveitar para simular entradas de razão. Mesmo sem frameworks sofisticados, você pode ter um CSV fictício e transações de saída esperadas, e verificar se seu script de importação produz as entradas corretas. Se você usa
pytest, pode integrar esses testes facilmente (como Alex Watt fez via um comandojust testenvolvendo o pytest). -
Controle de Versão: Mantenha seu razão e scripts sob controle de versão (git). Isso não apenas lhe dá backups e histórico, mas o incentiva a fazer mudanças de forma controlada. Você pode marcar releases dos seus "scripts financeiros" ou revisar diferenças ao depurar um problema. Alguns usuários até rastreiam seus registros financeiros no Git para ver mudanças ao longo do tempo. Apenas tenha cuidado para ignorar dados sensíveis (como arquivos de extrato brutos ou chaves de API) no seu repositório.
-
Documentação: Documente seus fluxos de trabalho personalizados para o seu eu futuro. Um README no seu repositório explicando como configurar o ambiente, como executar cada script e o que cada um faz será inestimável depois de meses. Também comente seu código, especialmente qualquer lógica contábil não óbvia ou interação com API.
-
Manutenção de Plugins do Fava: Se você escrever uma extensão do Fava, mantenha-a simples. O Fava pode mudar, então extensões menores com funcionalidade direcionada são mais fáceis de atualizar. Evite duplicar muita lógica – use o motor de consulta do Beancount ou funções auxiliares existentes sempre que possível, em vez de codificar cálculos que podem ser sensíveis a mudanças no razão.
-
Segurança: Como seus scripts podem lidar com dados sensíveis e se conectar a serviços externos, trate-os com cuidado. Não exponha chaves de API, e considere executar sua automação em uma máquina segura. Se você usa uma solução hospedada ou nuvem (como agendar GitHub Actions ou um servidor para executar o Fava), garanta que os dados do seu razão estejam criptografados em repouso e que você esteja confortável com as implicações de privacidade.
Seguindo essas práticas, você garante que seu fluxo de trabalho permaneça confiável mesmo à medida que suas finanças (e as próprias ferramentas) evoluem. Você quer scripts que possa reutilizar ano após ano, com ajustes mínimos.
Conclusão
O Beancount e o Fava fornecem uma plataforma poderosa e flexível para usuários experientes em tecnologia personalizarem completamente o acompanhamento de suas finanças pessoais. Escrevendo scripts Python, você pode automatizar tarefas tediosas como reconciliar extratos, produzir relatórios ricos adaptados às suas necessidades e manter-se em dia com suas finanças com alertas oportunos. Cobrimos uma variedade de exemplos, do básico ao avançado – começando com consultas simples e importações de CSV, e avançando para plugins completos do Fava e integrações com APIs externas. À medida que você implementa isso, comece simples e construa gradualmente. Mesmo alguns pequenos scripts de automação podem economizar horas de trabalho e melhorar enormemente a precisão. E lembre-se: como tudo é texto simples e Python, você está no controle total – seu sistema financeiro cresce com você, adaptando-se às suas necessidades específicas. Boa programação!
Fontes: As técnicas acima são extraídas da documentação do Beancount e de experiências da comunidade. Para leitura adicional, veja a documentação oficial do Beancount, guias e blogs da comunidade, e o repositório Awesome Beancount para links de plugins e ferramentas úteis.