Saltar al contenido principal

Flujos de Trabajo Programables con Beancount y Fava

Beancount (una herramienta de contabilidad de doble entrada en texto plano) y Fava (su interfaz web) son altamente extensibles y programables. Su diseño te permite automatizar tareas financieras, generar informes personalizados y configurar alertas escribiendo scripts de Python. En palabras de un usuario, “Realmente me gusta tener mis datos en un formato tan conveniente, y me gusta poder automatizar las cosas a mi gusto. No hay API como un archivo en tu disco; es fácil integrarlo.” Esta guía te guiará a través de la creación de flujos de trabajo programables, desde la automatización amigable para principiantes hasta los plugins avanzados de Fava.

Primeros Pasos: Ejecutar Beancount como un Script de Python

scriptable-workflows

Antes de sumergirte en tareas específicas, asegúrate de tener Beancount instalado (p. ej., a través de pip install beancount). Dado que Beancount está escrito en Python, puedes usarlo como una biblioteca en tus propios scripts. El enfoque general es:

  • Cargar tu libro mayor de Beancount: Utiliza el cargador de Beancount para analizar el archivo .beancount en objetos de Python. Por ejemplo:

    from beancount import loader
    entries, errors, options_map = loader.load_file("myledger.beancount")
    if errors:
    print("Errors:", errors)

    Esto te da una lista de entries (transacciones, saldos, etc.) y un options_map con metadatos. Todos tus cuentas, transacciones y saldos ahora son accesibles en el código.

  • Aprovechar el Lenguaje de Consulta de Beancount (BQL): En lugar de iterar manualmente, puedes ejecutar consultas tipo SQL en los datos. Por ejemplo, para obtener los gastos totales por mes, podrías utilizar la API de consulta:

    from beancount.query import query
    q = query.Query(entries, options_map)
    result = q.query("SELECT month, sum(position) WHERE account ~ 'Expenses' GROUP BY month")
    print(result)

    Esto utiliza el sistema de Consulta de Beancount para agregar datos. (En el fondo, esto es similar a lo que hace el comando bean-query, pero aquí lo estás usando en un script). De hecho, el autor de Beancount señala que puedes cargar el archivo y llamar a run_query() directamente a través de la API de Python, evitando la necesidad de llamar a comandos externos en un bucle.

  • Configurar una estructura de proyecto: Organiza tus scripts junto a tu libro mayor. Un diseño común es tener directorios para importadores (para obtener/analizar datos externos), informes o consultas (para scripts de análisis) y documentos (para almacenar estados de cuenta descargados). Por ejemplo, un usuario mantiene:

    • importers/ – scripts de importación personalizados de Python (con pruebas),
    • queries/ – scripts para generar informes (ejecutables a través de python3 queries/...),
    • documents/ – CSV/PDF bancarios descargados organizados por cuenta.

Con esta configuración, puedes ejecutar scripts manualmente (p. ej., python3 queries/cash_flow.py) o programarlos (a través de cron o un task runner) para automatizar tu flujo de trabajo.

Automatización de Tareas de Conciliación

Conciliación significa asegurarse de que tu libro mayor coincida con los registros externos (estados de cuenta bancarios, informes de tarjetas de crédito, etc.). El libro mayor en texto plano y la API de Python de Beancount hacen posible automatizar gran parte de este proceso.

Importación y Coincidencia de Transacciones (Principiante)

Para principiantes, el enfoque recomendado es utilizar los plugins de importación de Beancount. Escribes una pequeña clase de Python siguiendo el protocolo de importación de Beancount para analizar un formato dado (CSV, OFX, PDF, etc.) y producir transacciones. Luego, utiliza el comando bean-extract o un script para aplicar estos importadores:

  • Escribe un importador (una clase de Python con métodos como identify(), extract()) para el formato CSV de tu banco. La documentación de Beancount proporciona una guía y ejemplos.
  • Utiliza bean-extract en un script o Makefile (como el ejemplo de justfile) para analizar nuevos estados de cuenta. Por ejemplo, un flujo de trabajo ejecuta bean-extract en todos los archivos en ~/Downloads y genera transacciones a un archivo temporal.
  • Revisa y copia manualmente las transacciones del archivo temporal a tu libro mayor principal, luego ejecuta bean-check para asegurarte de que los saldos concilien.

Si bien este proceso todavía implica un paso de revisión, gran parte del trabajo pesado de análisis y formato de entradas está automatizado. Los scripts de importación también pueden asignar automáticamente categorías e incluso establecer afirmaciones de saldo (declaraciones de saldos esperados) para detectar discrepancias. Por ejemplo, después de importar, podrías tener una línea como 2025-04-30 balance Assets:Bank:Checking 1234.56 USD que afirma el saldo de cierre. Cuando ejecutas bean-check, Beancount verificará que todas estas afirmaciones de saldo sean correctas, y marcará cualquier error si faltan o se duplican transacciones. Esta es una buena práctica: genera automáticamente afirmaciones de saldo para cada período de estado de cuenta para que la computadora detecte las diferencias no conciliadas por ti.

Scripts de Conciliación Personalizados (Intermedio)

Para un mayor control, puedes escribir un script de Python personalizado para comparar la lista de transacciones de un banco (CSV o vía API) con las entradas de tu libro mayor:

  1. Leer los datos externos: Analiza el archivo CSV del banco utilizando el módulo csv de Python (o Pandas). Normaliza los datos en una lista de transacciones, p. ej., cada una con una fecha, monto y descripción.
  2. Cargar las transacciones del libro mayor: Utiliza loader.load_file como se mostró anteriormente para obtener todas las entradas del libro mayor. Filtra esta lista a la cuenta de interés (p. ej., tu cuenta corriente) y quizás el rango de fechas del estado de cuenta.
  3. Comparar y encontrar desajustes:
  • Para cada transacción externa, verifica si existe una entrada idéntica en el libro mayor (coincidencia por fecha y monto, tal vez descripción). Si no se encuentra, márcala como “nueva” y posiblemente genérala como una transacción con formato Beancount para que la revises.
  • A la inversa, identifica cualquier entrada del libro mayor en esa cuenta que no aparezca en la fuente externa; estos podrían ser errores de entrada de datos o transacciones que no se han liquidado en el banco.
  1. Generar resultados: Imprime un informe o crea un nuevo fragmento .beancount con las transacciones faltantes.

Como ejemplo, un script de la comunidad llamado reconcile.py hace exactamente esto: dado un archivo Beancount y un CSV de entrada, imprime una lista de nuevas transacciones que deberían importarse, así como cualquier asiento existente del libro mayor que no esté en la entrada (potencialmente un signo de clasificación errónea). Con dicho script, la conciliación mensual puede ser tan simple como ejecutarlo y luego agregar las transacciones sugeridas a tu libro mayor. Un usuario de Beancount señala que “realiza un proceso de conciliación en todas las cuentas cada mes” y utiliza una colección creciente de código Python para eliminar gran parte del trabajo manual en la importación y conciliación de datos.

Consejo: Durante la conciliación, aprovecha las herramientas de Beancount para obtener precisión:

  • Utiliza afirmaciones de saldo como se mencionó, para tener comprobaciones automatizadas de los saldos de las cuentas.
  • Utiliza la directiva pad si lo deseas, que puede insertar automáticamente entradas de compensación para pequeñas diferencias de redondeo (utiliza con precaución).
  • Escribe pruebas unitarias para tu importador o lógica de conciliación (Beancount proporciona ayudantes de prueba). Por ejemplo, un flujo de trabajo implicó tomar un CSV de muestra, escribir pruebas fallidas con las transacciones esperadas, luego implementar el importador hasta que todas las pruebas pasaran. Esto asegura que tu script de importación funcione correctamente para varios casos.

Generación de Informes y Resúmenes Personalizados

Si bien Fava proporciona muchos informes estándar (Estado de Resultados, Balance General, etc.), puedes crear informes personalizados utilizando scripts. Estos pueden variar desde salidas de consola simples hasta archivos o gráficos con formato enriquecido.

Consulta de Datos para Informes (Principiante)

A un nivel básico, puedes utilizar el Lenguaje de Consulta de Beancount (BQL) para obtener datos resumidos e imprimirlos o guardarlos. Por ejemplo:

  • Resumen de Flujo de Caja: Utiliza una consulta para calcular el flujo de caja neto. El "flujo de caja" podría definirse como el cambio en el saldo de ciertas cuentas durante un período. Usando BQL, podrías hacer:

    SELECT year, month, sum(amount)
    WHERE account LIKE 'Income:%' OR account LIKE 'Expenses:%'
    GROUP BY year, month

    Esto netearía todos los ingresos y gastos por mes. Podrías ejecutar esto a través de la CLI bean-query o mediante la API de Python (query.Query como se mostró anteriormente) y luego formatear el resultado.

  • Informe de Gastos por Categoría: Consulta los gastos totales por categoría:

    SELECT account, round(sum(position), 2)
    WHERE account ~ 'Expenses'
    GROUP BY account
    ORDER BY sum(position) ASC

    Esto produce una tabla de gastos por categoría. Puedes ejecutar varias consultas en un script y generar los resultados como texto, CSV o incluso JSON para su posterior procesamiento.

Un usuario encontró “trivial” analizar los datos financieros con Fava o con scripts, citando que utiliza un script de Python para extraer datos de Beancount a través del Lenguaje de Consulta y luego colocarlos en un DataFrame de Pandas para preparar un informe personalizado. Por ejemplo, podrías obtener los totales mensuales con una consulta y luego usar Pandas/Matplotlib para trazar un gráfico de flujo de caja a lo largo del tiempo. La combinación de BQL y las bibliotecas de ciencia de datos te permite crear informes más allá de lo que ofrece Fava de forma predeterminada.

Informes Avanzados (Gráficos, Rendimiento, etc.)

Para necesidades más avanzadas, tus scripts pueden calcular métricas como el rendimiento de la inversión o crear salidas visuales:

  • Rendimiento de la Inversión (TIR/TIRR): Dado que tu libro mayor contiene todos los flujos de caja (compras, ventas, dividendos), puedes calcular las tasas de rendimiento de la cartera. Por ejemplo, podrías escribir un script que filtre las transacciones de tus cuentas de inversión y luego calcule la Tasa Interna de Retorno. Existen bibliotecas (o fórmulas) para calcular la TIR dados los datos de flujo de caja. Algunas extensiones de Fava desarrolladas por la comunidad (como PortfolioSummary o fava_investor) hacen exactamente esto, calculando la TIR y otras métricas para carteras de inversión. Como script, podrías usar una función TIR (de NumPy o la tuya propia) en la serie de contribuciones/retiros más el valor final.

  • Métricas Multi-período o Personalizadas: ¿Quieres un informe de tu tasa de ahorro (relación entre el ahorro y los ingresos) cada mes? Un script de Python puede cargar el libro mayor, sumar todas las cuentas de Ingresos y todas las cuentas de Gastos, luego calcular el ahorro = ingresos - gastos y el porcentaje. Esto podría generar una tabla agradable o incluso generar un informe HTML/Markdown para tus registros.

  • Visualización: Puedes generar gráficos fuera de Fava. Por ejemplo, utiliza matplotlib o altair en un script para crear un gráfico de patrimonio neto a lo largo del tiempo, utilizando los datos del libro mayor. Debido a que el libro mayor tiene todos los saldos históricos (o puedes acumularlos iterando las entradas), puedes producir diagramas de series de tiempo. Guarda estos gráficos como imágenes o HTML interactivo. (Si prefieres las visualizaciones dentro de la aplicación, consulta la sección de extensión de Fava a continuación para agregar gráficos dentro de Fava).

Opciones de Salida: Decide cómo entregar el informe:

  • Para análisis únicos, imprimir en la pantalla o guardar en un archivo CSV/Excel podría ser suficiente.
  • Para paneles, considera generar un archivo HTML con los datos (posiblemente utilizando una biblioteca de plantillas como Jinja2 o incluso simplemente escribiendo Markdown) que puedas abrir en un navegador.
  • También puedes integrarte con Jupyter Notebooks para un entorno de informes interactivo, aunque eso es más para la exploración que para la automatización.

Activación de Alertas desde tu Libro Mayor

Otro uso poderoso de los flujos de trabajo programables es la configuración de alertas basadas en condiciones en tus datos financieros. Debido a que tu libro mayor se actualiza regularmente (y puede incluir elementos con fecha futura, como próximas facturas o presupuestos), puedes escanearlo con un script y recibir notificaciones de eventos importantes.

Advertencias de Saldo Bajo en la Cuenta

Para evitar sobregiros o mantener un saldo mínimo, es posible que desees una alerta si alguna cuenta (p. ej., corriente o de ahorros) cae por debajo de un umbral. Aquí te mostramos cómo puedes implementar esto:

  1. Determinar los saldos actuales: Después de cargar entries a través del cargador, calcula el saldo más reciente de las cuentas de interés. Puedes hacer esto agregando asientos o usando una consulta. Por ejemplo, utiliza una consulta BQL para el saldo de una cuenta específica:

    SELECT sum(position) WHERE account = 'Assets:Bank:Checking'

    Esto devuelve el saldo actual de esa cuenta (suma de todos sus asientos). Alternativamente, utiliza las funciones internas de Beancount para construir un balance general. Por ejemplo:

    from beancount.core import realization
    tree = realization.realize(entries, options_map)
    acct = realization.get_or_create(tree, "Assets:Bank:Checking")
    balance = acct.balance # an Inventory of commodities

    Luego extrae el valor numérico (p. ej., balance.get_currency_units('USD') podría dar el Decimal). Sin embargo, el uso de la consulta es más simple para la mayoría de los casos.

  2. Verificar el umbral: Compara el saldo con tu límite predefinido. Si está por debajo, activa una alerta.

  3. Activar notificación: Esto podría ser tan simple como imprimir una advertencia en la consola, pero para alertas reales podrías enviar un correo electrónico o una notificación push. Puedes integrarte con el correo electrónico (a través de smtplib) o un servicio como IFTTT o la API de webhook de Slack para enviar la alerta. Por ejemplo:

    if balance < 1000:
    send_email("Low balance alert", f"Account XYZ balance is {balance}")

    (Implementa send_email con los detalles de tu servidor de correo electrónico).

Al ejecutar este script diariamente (a través de un trabajo cron o el Programador de tareas de Windows), obtendrás advertencias proactivas. Debido a que está utilizando el libro mayor, puede considerar todas las transacciones, incluidas las que acabas de agregar.

Próximas Fechas Límite de Pago

Si utilizas Beancount para realizar un seguimiento de las facturas o las fechas límite, puedes marcar los pagos futuros y hacer que los scripts te recuerden. Dos formas de representar las próximas obligaciones en Beancount:

  • Eventos: Beancount admite una directiva event para notas fechadas arbitrarias. Por ejemplo:

    2025-05-10 event "BillDue" "Mortgage payment due"

    Esto no afecta los saldos, pero registra una fecha con una etiqueta. Un script puede escanear entries para las entradas Event donde Event.type == "BillDue" (o cualquier tipo personalizado que elijas) y verificar si la fecha está dentro de, digamos, los próximos 7 días a partir de hoy. Si es así, activa una alerta (correo electrónico, notificación o incluso una ventana emergente).

  • Transacciones Futuras: Algunas personas ingresan transacciones con fecha futura (fechadas posteriormente) para cosas como pagos programados. Estos no aparecerán en los saldos hasta que pase la fecha (a menos que ejecutes informes a partir de fechas futuras). Un script puede buscar transacciones fechadas en un futuro cercano y enumerarlas.

Utilizando esto, podrías crear un script de "recordatorio" que, cuando se ejecute, genere una lista de tareas o facturas que vencen pronto. Intégrate con una API como Google Calendar o un administrador de tareas si deseas crear automáticamente recordatorios allí.

Detección de Anomalías

Más allá de los umbrales o fechas conocidos, puedes programar alertas personalizadas para patrones inusuales. Por ejemplo, si un gasto normalmente mensual no ha ocurrido (tal vez olvidaste pagar una factura), o si el gasto de una categoría es anormalmente alto este mes, tu script podría marcarlo. Esto generalmente implica consultar datos recientes y compararlos con el historial (lo que podría ser un tema avanzado, posiblemente empleando estadísticas o ML).

En la práctica, muchos usuarios confían en la conciliación para detectar anomalías (transacciones inesperadas). Si recibes notificaciones bancarias (como correos electrónicos para cada transacción), podrías analizarlas con un script y agregarlas automáticamente a Beancount, o al menos verificar que estén registradas. Un entusiasta incluso configuró su banco para que enviara correos electrónicos de alerta de transacciones, con el plan de analizarlos y agregarlos automáticamente al libro mayor. Este tipo de alerta basada en eventos puede garantizar que ninguna transacción quede sin registrar.

Extensión de Fava con Plugins y Vistas Personalizadas

Fava ya es programable a través de su sistema de extensión. Si deseas que tu automatización o informes se integren directamente en la interfaz web, puedes escribir una extensión de Fava (también llamada plugin) en Python.

Cómo Funcionan las Extensiones de Fava: Una extensión es un módulo de Python que define una clase que hereda de fava.ext.FavaExtensionBase. La registras en tu archivo Beancount a través de una opción personalizada. Por ejemplo, si tienes un archivo myextension.py con una clase MyAlerts(FavaExtensionBase), puedes habilitarlo agregándolo a tu libro mayor:

1970-01-01 custom "fava-extension" "myextension"

Cuando Fava se carga, importará ese módulo e inicializará tu clase MyAlerts.

Las extensiones pueden hacer varias cosas:

  • Hooks: Pueden engancharse a eventos en el ciclo de vida de Fava. Por ejemplo, after_load_file() se llama después de que se carga el libro mayor. Podrías utilizar esto para ejecutar comprobaciones o precalcular datos. Si deseas implementar la verificación de saldo bajo dentro de Fava, after_load_file podría iterar sobre los saldos de las cuentas y quizás almacenar advertencias (aunque mostrarlas en la UI podría requerir un poco más de trabajo, como generar un FavaAPIError o usar Javascript para mostrar una notificación).
  • Informes/Páginas Personalizadas: Si tu clase de extensión establece un atributo report_title, Fava agregará una nueva página en la barra lateral para ello. Luego proporcionas una plantilla (HTML/Jinja2) para el contenido de esa página. Así es como creas vistas completamente nuevas, como un panel o un resumen que Fava no tiene de forma predeterminada. La extensión puede recopilar los datos que necesite (puedes acceder a self.ledger que tiene todas las entradas, saldos, etc.) y luego renderizar la plantilla.

Por ejemplo, la extensión integrada portfolio_list en Fava agrega una página que enumera las posiciones de tu cartera. Las extensiones de la comunidad van más allá:

  • Paneles: El plugin fava-dashboards permite definir gráficos y paneles personalizados (utilizando bibliotecas como Apache ECharts). Lee una configuración YAML de consultas para ejecutar, las ejecuta a través de Beancount y genera una página de panel dinámico en Fava. En esencia, une los datos de Beancount y una biblioteca de gráficos de JavaScript para producir visualizaciones interactivas.
  • Análisis de cartera: La extensión PortfolioSummary (aportada por el usuario) calcula resúmenes de inversión (agrupando cuentas, calculando la TIR, etc.) y los muestra en la UI de Fava.
  • Revisión de transacciones: Otra extensión, fava-review, ayuda a revisar las transacciones a lo largo del tiempo (p. ej., para asegurarse de que no te perdiste ningún recibo).

Para crear una extensión simple tú mismo, comienza por subclasificar FavaExtensionBase. Por ejemplo, una extensión mínima que agrega una página podría verse así:

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")

Si colocaras esto en hello.py y agregaras custom "fava-extension" "hello" a tu libro mayor, Fava mostraría una nueva página "Hello World" (también necesitarías un archivo de plantilla HelloReport.html en una subcarpeta templates para definir el contenido de la página, a menos que la extensión solo use hooks). La plantilla puede usar los datos que adjuntes a la clase de extensión. Fava utiliza plantillas Jinja2, por lo que podrías renderizar tus datos en una tabla HTML o un gráfico en esa plantilla.

Nota: El sistema de extensión de Fava es poderoso pero se considera “inestable” (sujeto a cambios). Requiere cierta familiaridad con el desarrollo web (HTML/JS) si estás creando páginas personalizadas. Si tu objetivo es simplemente ejecutar scripts o análisis, podría ser más fácil mantenerlos como scripts externos. Utiliza las extensiones de Fava cuando desees una experiencia en la aplicación personalizada para tu flujo de trabajo.

Integración de APIs y Datos de Terceros

Una de las ventajas de los flujos de trabajo programables es la capacidad de incorporar datos externos. Aquí hay integraciones comunes:

  • Tipos de Cambio y Productos Básicos: Beancount no obtiene automáticamente los precios por diseño (para mantener los informes deterministas), pero proporciona una directiva Price para que proporciones las tarifas. Puedes automatizar la obtención de estos precios. Por ejemplo, un script puede consultar una API (Yahoo Finance, Alpha Vantage, etc.) para obtener el último tipo de cambio o el precio de las acciones y agregar una entrada de precio a tu libro mayor:

    2025-04-30 price BTC 30000 USD
    2025-04-30 price EUR 1.10 USD

    Existen herramientas como bean-price (ahora una herramienta externa bajo el paraguas de Beancount) que obtienen cotizaciones diarias y las generan en formato Beancount. Podrías programar bean-price para que se ejecute cada noche para actualizar un archivo de inclusión prices.beancount. O utilizar Python: p. ej., con la biblioteca requests para llamar a una API. La documentación de Beancount sugiere que para los activos que cotizan en bolsa, puedes “invocar algún código que descargue los precios y escriba las directivas por ti”. En otras palabras, permite que un script haga la búsqueda e inserte las líneas price, en lugar de que lo hagas manualmente.

  • Datos de la Cartera de Acciones: De forma similar a los tipos de cambio, puedes integrarte con las API para obtener datos detallados de las acciones o los dividendos. Por ejemplo, la API de Yahoo Finance (o las bibliotecas de la comunidad como yfinance) puede recuperar datos históricos para un ticker. Un script podría actualizar tu libro mayor con el historial de precios mensuales de cada acción que posees, lo que permite informes históricos precisos del valor de mercado. Algunas extensiones personalizadas (como fava_investor) incluso extraen datos de precios sobre la marcha para mostrarlos, pero lo más simple es importar regularmente los precios al libro mayor.

  • APIs Bancarias (Open Banking/Plaid): En lugar de descargar CSV, puedes utilizar las API para obtener transacciones automáticamente. Servicios como Plaid agregan cuentas bancarias y permiten el acceso programático a las transacciones. En una configuración avanzada, podrías tener un script de Python que utilice la API de Plaid para extraer nuevas transacciones diariamente y guardarlas en un archivo (o importarlas directamente al libro mayor). Un usuario avanzado construyó un sistema donde Plaid alimenta su canalización de importación, haciendo que sus libros sean casi automáticos. Señalan que “nada te impide registrarte en la API de Plaid y hacer lo mismo localmente”; es decir, puedes escribir un script local para obtener datos bancarios, luego usar tu lógica de importador Beancount para analizarlos en entradas de libro mayor. Algunas regiones tienen API de banca abierta proporcionadas por los bancos; esas podrían usarse de manera similar.

  • Otras APIs: Podrías integrar herramientas de presupuesto (exportando presupuestos planificados para comparar con los reales en Beancount), o utilizar una API de OCR para leer recibos y hacerlos coincidir automáticamente con las transacciones. Debido a que tus scripts tienen acceso completo al ecosistema de Python, puedes integrar todo, desde servicios de correo electrónico (para enviar alertas) hasta Hojas de cálculo de Google (p. ej., actualizar una hoja con métricas financieras mensuales) hasta aplicaciones de mensajería (enviarte un informe resumido a través de un bot de Telegram).

Cuando utilices APIs de terceros, recuerda asegurar tus credenciales (utiliza variables de entorno o archivos de configuración para las claves API) y manejar los errores (problemas de red, tiempo de inactividad de la API) con elegancia en tus scripts. A menudo es prudente almacenar datos en caché (por ejemplo, almacenar los tipos de cambio obtenidos para no solicitar la misma tarifa histórica repetidamente).

Mejores Prácticas para Scripts Modulares y Mantenibles

A medida que desarrollas flujos de trabajo programables, mantén tu código organizado y robusto:

  • Modularidad: Divide las diferentes preocupaciones en diferentes scripts o módulos. Por ejemplo, ten scripts separados para “importación/conciliación de datos” vs. “generación de informes” vs. “alertas”. Incluso puedes crear un pequeño paquete de Python para tu libro mayor con módulos como ledger_import.py, ledger_reports.py, etc. Esto hace que cada parte sea más fácil de entender y probar.

  • Configuración: Evita los valores codificados. Utiliza un archivo de configuración o variables en la parte superior del script para cosas como nombres de cuentas, umbrales, claves API, rangos de fechas, etc. Esto facilita el ajuste sin editar el código en profundidad. Por ejemplo, define LOW_BALANCE_THRESHOLDS = {"Assets:Bank:Checking": 500, "Assets:Savings": 1000} en la parte superior, y tu script de alerta puede recorrer este dict.

  • Pruebas: Trata tu automatización financiera como código de misión crítica, ¡porque lo es! Escribe pruebas para lógica compleja. Beancount proporciona algunos ayudantes de prueba (utilizados internamente para las pruebas del importador) que puedes aprovechar para simular entradas de libro mayor. Incluso sin marcos sofisticados, puedes tener un CSV ficticio y las transacciones de salida esperadas, y afirmar que tu script de importación produce las entradas correctas. Si utilizas pytest, puedes integrar estas pruebas fácilmente (como lo hizo Alex Watt a través de un comando just test que envuelve pytest).

  • Control de Versiones: Mantén tu libro mayor y tus scripts bajo control de versiones (git). Esto no solo te brinda copias de seguridad e historial, sino que te anima a realizar cambios de manera controlada. Puedes etiquetar las versiones de tus “scripts de finanzas” o revisar las diferencias al depurar un problema. Algunos usuarios incluso rastrean sus registros financieros en Git para ver los cambios a lo largo del tiempo. Solo ten cuidado de ignorar los datos confidenciales (como los archivos de extractos sin procesar o las claves API) en tu repositorio.

  • Documentación: Documenta tus flujos de trabajo personalizados para tu futuro yo. Un archivo README en tu repositorio que explique cómo configurar el entorno, cómo ejecutar cada script y qué hace cada uno será invaluable después de que hayan pasado meses. También comenta tu código, especialmente cualquier lógica contable o interacción API no obvia.

  • Mantenimiento de Plugins de Fava: Si escribes una extensión de Fava, mantenla simple. Fava podría cambiar, por lo que las extensiones más pequeñas con funcionalidad dirigida son más fáciles de actualizar. Evita duplicar demasiada lógica; utiliza el motor de consulta de Beancount o las funciones de ayuda existentes siempre que sea posible, en lugar de codificar cálculos que podrían ser sensibles a los cambios en el libro mayor.

  • Seguridad: Dado que tus scripts pueden manejar datos confidenciales y conectarse a servicios externos, trátalos con cuidado. No expongas las claves API y considera ejecutar tu automatización en una máquina segura. Si utilizas una solución alojada o la nube (como programar Acciones de GitHub o un servidor para ejecutar Fava), asegúrate de que los datos de tu libro mayor estén encriptados en reposo y de que te sientas cómodo con las implicaciones de privacidad.

Siguiendo estas prácticas, te aseguras de que tu flujo de trabajo siga siendo confiable incluso a medida que tus finanzas (y las herramientas en sí) evolucionen. Quieres scripts que puedas reutilizar año tras año, con modificaciones mínimas.

Conclusión

Beancount y Fava proporcionan una plataforma poderosa y flexible para que los usuarios expertos en tecnología personalicen completamente su seguimiento de finanzas personales. Al escribir scripts de Python, puedes automatizar tareas tediosas como la conciliación de extractos, producir informes enriquecidos adaptados a tus necesidades y mantenerte al tanto de tus finanzas con alertas oportunas. Cubrimos una gama de ejemplos desde básicos hasta avanzados, comenzando con consultas simples e importaciones CSV, y pasando a plugins Fava completos e integraciones de API externas. A medida que implementes esto, comienza de forma sencilla y aumenta gradualmente. Incluso algunos pequeños scripts de automatización pueden ahorrar horas de trabajo y mejorar enormemente la precisión. Y recuerda, como todo es texto plano y Python, tienes el control total: tu sistema financiero crece contigo, adaptándose a tus necesidades específicas. ¡Feliz scripting!

Fuentes: Las técnicas anteriores se extraen de la documentación de Beancount y las experiencias de la comunidad. Para obtener más información, consulta los documentos oficiales de Beancount, las guías y blogs de la comunidad y el repositorio Awesome Beancount para obtener enlaces a plugins y herramientas útiles.