Una Guía para la Precisión y las Tolerancias en Beancount
Gestionar la precisión numérica es una piedra angular de la contabilidad por partida doble. En la teneduría de libros digital, especialmente cuando se trabaja con múltiples divisas, precios de acciones y acciones fraccionarias, pequeñas discrepancias de redondeo pueden conducir rápidamente a frustrantes errores de balance. Beancount proporciona un sistema sofisticado pero intuitivo para manejar la precisión y establecer tolerancias aceptables. Esta guía le explicará cómo funciona. ⚙️
Conceptos Centrales de Precisión
El objetivo principal de Beancount es asegurar que cada transacción se balancee a cero. Sin embargo, los cálculos que involucran precios o costos a menudo producen resultados con más decimales de los que es práctico registrar. El sistema de tolerancia permite pequeños desequilibrios aceptables.
Inferencia Automática de Tolerancia
Por defecto, Beancount infiere la tolerancia requerida para cada transacción automáticamente. Esta inferencia se maneja individualmente para cada transacción y se calcula por separado para cada divisa involucrada.
La regla es simple: la tolerancia es la mitad del último dígito significativo de los números presentes en los asientos de la transacción.
Por ejemplo, considere esta compra:
2013-04-03 * "Comprar Fondo"
Assets:Fund 10.22626 FUND {37.61 USD}
Assets:Cash -384.61 USD
Beancount infiere las tolerancias de la siguiente manera:
- Para la materia prima
FUND, el número10.22626tiene 5 decimales. La tolerancia es la mitad del último dígito, por lo queFUND. - Para la materia prima
USD, el número-384.61tiene 2 decimales. La tolerancia es la mitad del último dígito, por lo queUSD.
Reglas de Peso de la Transacción
Al verificar si una transacción se balancea, Beancount calcula el "peso" de cada asiento. Las reglas para este cálculo son:
- Cantidad Simple: Si un asiento solo tiene una cantidad (por ejemplo,
Assets:Cash -100.00 USD), su peso es esa cantidad exacta. - Asiento de Precio: Si un asiento tiene un precio por unidad (por ejemplo,
10 FUND @ 38.46 USD), su peso es lacantidad × precio. - Asiento de Costo: Si un asiento tiene un costo total (por ejemplo,
10 FUND {384.61 USD}), su peso es la cantidad del costo total. - Costo y Precio: Si un asiento tiene tanto un costo total como un precio por unidad (por ejemplo,
10 FUND {384.61 USD} @ 38.46 USD), solo se usa el costo total para el balance. El precio por unidad se trata como un comentario o memo.
Reglas de Inferencia de Precisión
El sistema de inferencia automática sigue algunas reglas específicas:
- Formato de Número
- Las cantidades enteras (por ejemplo,
10 USD) no contribuyen a la inferencia de precisión. - La tolerancia máxima que se puede inferir automáticamente es de
0.05unidades (por ejemplo, de un número como10.1 USD). Si necesita una tolerancia mayor, debe especificarla manualmente. - Los costos y los precios (por ejemplo,
{37.61 USD}) están excluidos de la inferencia de tolerancia. Solo se utilizan las cantidades primarias de los asientos. - Si los asientos para la misma divisa tienen diferentes precisiones (por ejemplo,
-10.10 USDy5.123 USD), Beancount utiliza la tolerancia más gruesa (mayor). En este caso, se basaría en-10.10 USD, lo que daría una tolerancia deUSD.
-
Manejo por Defecto Puede establecer una tolerancia predeterminada global o específica de la divisa si una transacción no tiene números con decimales a partir de los cuales inferirla.
; Establece una tolerancia predeterminada para todas las divisas sin reglas explícitas
option "inferred_tolerance_default" "*:0.001"
; Establece una tolerancia predeterminada específica para USD
option "inferred_tolerance_default" "USD:0.003" -
Multiplicador de Tolerancia Puede aumentar globalmente todas las tolerancias inferidas mediante un multiplicador fijo. Esto es útil para relajar las comprobaciones en todo su archivo sin cambiar cada transacción. Un multiplicador de
1.2aumenta todas las tolerancias inferidas en un 20%.option "inferred_tolerance_multiplier" "1.2" -
Inferencia Basada en Costos Si bien los costos normalmente se ignoran para la inferencia de tolerancia, puede indicarle a Beancount que los use. Esto es útil cuando la cantidad final (por ejemplo, un retiro de efectivo) es el número más preciso en una transacción.
option "infer_tolerance_from_cost" "TRUE"
Aserciones de Balance
Las aserciones de balance (balance) se utilizan para verificar que el balance de su cuenta coincida con un valor conocido en una fecha específica. También tienen una tolerancia asociada.
Formato Básico
Similar a las transacciones, la tolerancia para una aserción balance se infiere del número de decimales en la cantidad.
; Afirma que el balance es 4.271 RGAGX con una tolerancia de ±0.0005
2015-05-08 balance Assets:Fund 4.271 RGAGX
; Afirma que el balance es 4.27 RGAGX con una tolerancia de ±0.005
2015-05-08 balance Assets:Fund 4.27 RGAGX
El balance calculado debe estar dentro de este rango. Para el segundo ejemplo, cualquier balance entre y pasaría la verificación.
Tolerancias Explícitas
Si la tolerancia inferida no es adecuada, puede especificar una explícitamente utilizando el carácter tilde (~).
; Afirma que el balance es 4.271 RGAGX con una tolerancia personalizada de ±0.01 RGAGX
2015-05-08 balance Assets:Fund 4.271 ~ 0.01 RGAGX
Aquí, la aserción pasará si el balance calculado está entre y RGAGX.
Gestión de Redondeo
Para los casos en que se esperan y son aceptables pequeños residuos de los cálculos, Beancount proporciona herramientas para gestionarlos sistemáticamente.
Seguimiento de Errores de Redondeo
Puede designar una cuenta especial para recopilar automáticamente los errores de redondeo. Esto mantiene sus transacciones perfectamente balanceadas al barrer pequeñas cantidades sobrantes en un solo lugar.
Primero, habilite la opción y abra la cuenta:
option "account_rounding" "Equity:RoundingError"
2000-01-01 open Equity:RoundingError
Ahora, Beancount agregará automáticamente una tercera pata a cualquier transacción que no se balancee dentro de su tolerancia, contabilizando la diferencia en Equity:RoundingError.
2013-02-23 * "Compra"
Assets:Invest 1.245 RGAGX {43.23 USD}
Assets:Cash -53.82 USD
En esta transacción, . La transacción está desbalanceada por USD. Con la opción de redondeo habilitada, Beancount internamente la trata como:
2013-02-23 * "Compra"
Assets:Invest 1.245 RGAGX {43.23 USD}
Assets:Cash -53.82 USD
Equity:RoundingError -0.00135 USD ; Agregado automáticamente
Precisión de Número Inferida
Beancount también puede usar la configuración de tolerancia para redondear automáticamente los números antes de que se inserten en las estructuras de datos del libro.
-
Sin Tolerancia Especificada: Si no se define ninguna tolerancia, los números se utilizan con su precisión total. No se produce ningún redondeo.
-
Con Tolerancia Predeterminada: Si establece una tolerancia predeterminada, los números se cuantificarán a ese nivel.
option "default_tolerance" "USD:0.001"Con esta configuración, un número como
53.82135 USDse redondearía y se almacenaría como53.821 USD. -
Con Cuenta de Redondeo: Si tanto una tolerancia predeterminada como una cuenta de redondeo están activas, Beancount cuantifica el número y captura el residuo.
option "default_tolerance" "USD:0.01"
option "account_rounding" "Equity:RoundingError"Un número como
53.82135 USDse almacenaría como53.82 USD, y el residuo de-0.00135 USDse contabilizaría enEquity:RoundingError.
Detalles de Implementación
Algunos puntos técnicos aclaran cómo Beancount logra esta confiabilidad.
-
Representación de Números: Beancount utiliza el módulo
decimalde Python, no números de punto flotante. Esto permite hasta 28 decimales de precisión y evita los errores de representación binaria comunes a los flotantes. -
Clase DisplayContext: Esta clase interna maneja todo el formato de número para fines de visualización. Respeta la configuración de precisión específica de la divisa y puede formatear la salida con columnas alineadas y comas.
-
Precisión vs. Tolerancia: Es crucial distinguir estos dos conceptos:
- Precisión se relaciona con el formato de visualización de un número (cuántos decimales se muestran).
- Tolerancia es la concesión para el desequilibrio utilizada durante las comprobaciones de verificación.
Mejores Prácticas ✨
Aquí hay algunas recomendaciones prácticas para gestionar la precisión en su libro mayor.
Configuración Inicial
Para la mayoría de los libros mayores nuevos, esta es una configuración inicial sólida:
; Un valor predeterminado razonable para la mayoría de las divisas (por ejemplo, USD, EUR)
option "inferred_tolerance_default" "*:0.005"
; Un búfer del 10% en todas las tolerancias inferidas
option "inferred_tolerance_multiplier" "1.1"
; Una cuenta para capturar todo el polvo de redondeo
option "account_rounding" "Equity:RoundingError"
2000-01-01 open Equity:RoundingError
Consejos para la Solución de Problemas
Si encuentra errores de balance:
- Agregue dígitos decimales a la cantidad de un asiento para crear una inferencia de tolerancia local más ajustada y precisa.
- Use tolerancias explícitas (
~) en las asercionesbalanceque fallen debido a discrepancias predecibles. - Realice un seguimiento de los errores de redondeo en una cuenta dedicada para ver dónde y con qué frecuencia ocurren.
- Considere establecer valores predeterminados específicos de la divisa si con frecuencia trabaja con divisas que tienen diferentes convenciones (por ejemplo, JPY no tiene decimales).
Estrategia de Migración
Al aplicar estos conceptos a un libro mayor existente y desordenado:
- Comience con una tolerancia global generosa (por ejemplo,
*:0.05) y un multiplicador alto para que el archivo se valide. - Ajuste gradualmente las tolerancias y corrija los errores que aparezcan.
- Agregue dígitos explícitos a las cantidades en las transacciones problemáticas para permitir que la inferencia haga su trabajo.
- Supervise el balance de la cuenta de redondeo. Un balance grande o de rápido crecimiento puede indicar un problema sistémico que necesita investigación.