Guide de la précision et des tolérances dans Beancount
La gestion de la précision numérique est une pierre angulaire de la comptabilité en partie double. Dans la tenue de livres numérique, en particulier lors de la manipulation de plusieurs devises, de cours boursiers et d'actions fractionnaires, de petits écarts d'arrondi peuvent rapidement entraîner des erreurs d'équilibrage frustrantes. Beancount fournit un système sophistiqué mais intuitif pour gérer la précision et définir des tolérances acceptables. Ce guide vous expliquera son fonctionnement. ⚙️
Concepts fondamentaux de la précision
L'objectif principal de Beancount est de garantir que chaque transaction s'équilibre à zéro. Cependant, les calculs impliquant des prix ou des coûts produisent souvent des résultats avec plus de décimales qu'il n'est pratique d'enregistrer. Le système de tolérance permet de petits déséquilibres acceptables.
Inférence automatique de la tolérance
Par défaut, Beancount infère automatiquement la tolérance requise pour chaque transaction. Cette inférence est gérée individuellement pour chaque transaction et calculée séparément pour chaque devise impliquée.
La règle est simple : la tolérance est la moitié du dernier chiffre significatif des nombres présents dans les écritures de la transaction.
Par exemple, considérez cet achat :
2013-04-03 * "Achat de fonds"
Assets:Fund 10.22626 FUND {37.61 USD}
Assets:Cash -384.61 USD
Beancount infère les tolérances comme suit :
- Pour la devise
FUND, le nombre10.22626a 5 décimales. La tolérance est la moitié du dernier chiffre, doncFUND. - Pour la devise
USD, le nombre-384.61a 2 décimales. La tolérance est la moitié du dernier chiffre, doncUSD.
Règles de pondération des transactions
Lors de la vérification de l'équilibre d'une transaction, Beancount calcule le "poids" de chaque écriture. Les règles de ce calcul sont les suivantes :
- Montant simple : Si une écriture n'a qu'un montant (par exemple,
Assets:Cash -100.00 USD), son poids est ce montant exact. - Écriture de prix : Si une écriture a un prix unitaire (par exemple,
10 FUND @ 38.46 USD), son poids est lemontant × prix. - Écriture de coût : Si une écriture a un coût total (par exemple,
10 FUND {384.61 USD}), son poids est le montant du coût total. - Coût et prix : Si une écriture a à la fois un coût total et un prix unitaire (par exemple,
10 FUND {384.61 USD} @ 38.46 USD), seul le coût total est utilisé pour l'équilibrage. Le prix unitaire est traité comme un commentaire ou un mémo.
Règles d'inférence de la précision
Le système d'inférence automatique suit quelques règles spécifiques :
- Format numérique
- Les montants entiers (par exemple,
10 USD) ne contribuent pas à l'inférence de la précision. - La tolérance maximale qui peut être inférée automatiquement est de
0.05unités (par exemple, à partir d'un nombre comme10.1 USD). Si vous avez besoin d'une tolérance plus grande, vous devez la spécifier manuellement. - Les coûts et les prix (par exemple,
{37.61 USD}) sont exclus de l'inférence de la tolérance. Seuls les montants principaux des écritures sont utilisés. - Si les écritures pour la même devise ont des précisions différentes (par exemple,
-10.10 USDet5.123 USD), Beancount utilise la tolérance la moins précise (la plus grande). Dans ce cas, elle serait basée sur-10.10 USD, ce qui donnerait une tolérance deUSD.
-
Gestion par défaut Vous pouvez définir une tolérance par défaut globale ou spécifique à une devise si une transaction ne contient aucun nombre avec des décimales à partir duquel l'inférer.
; Définit une tolérance par défaut pour toutes les devises sans règles explicites
option "inferred_tolerance_default" "*:0.001"
; Définit une tolérance par défaut spécifique pour l'USD
option "inferred_tolerance_default" "USD:0.003" -
Multiplicateur de tolérance Vous pouvez augmenter globalement toutes les tolérances inférées par un multiplicateur fixe. Ceci est utile pour assouplir les contrôles sur l'ensemble de votre fichier sans modifier chaque transaction. Un multiplicateur de
1.2augmente toutes les tolérances inférées de 20 %.option "inferred_tolerance_multiplier" "1.2" -
Inférence basée sur le coût Bien que les coûts soient normalement ignorés pour l'inférence de la tolérance, vous pouvez demander à Beancount de les utiliser. Ceci est utile lorsque le montant final (par exemple, un retrait d'espèces) est le nombre le plus précis dans une transaction.
option "infer_tolerance_from_cost" "TRUE"
Assertions de solde
Les assertions de solde (balance) sont utilisées pour vérifier que le solde de votre compte correspond à une valeur connue à une date spécifique. Elles ont également une tolérance associée.
Format de base
Comme pour les transactions, la tolérance pour une assertion balance est inférée du nombre de décimales dans le montant.
; Asserte que le solde est de 4.271 RGAGX avec une tolérance de ±0.0005
2015-05-08 balance Assets:Fund 4.271 RGAGX
; Asserte que le solde est de 4.27 RGAGX avec une tolérance de ±0.005
2015-05-08 balance Assets:Fund 4.27 RGAGX
Le solde calculé doit se situer dans cette plage. Pour le deuxième exemple, tout solde entre et réussirait le contrôle.
Tolérances explicites
Si la tolérance inférée n'est pas appropriée, vous pouvez en spécifier une explicitement en utilisant le caractère tilde (~).
; Asserte que le solde est de 4.271 RGAGX avec une tolérance personnalisée de ±0.01 RGAGX
2015-05-08 balance Assets:Fund 4.271 ~ 0.01 RGAGX
Ici, l'assertion réussira si le solde calculé est compris entre et RGAGX.
Gestion des arrondis
Pour les cas où de petits résidus de calculs sont attendus et acceptables, Beancount fournit des outils pour les gérer systématiquement.
Suivi des erreurs d'arrondi
Vous pouvez désigner un compte spécial pour collecter automatiquement les erreurs d'arrondi. Cela permet de maintenir vos transactions parfaitement équilibrées en versant de minuscules montants restants dans un seul endroit.
Tout d'abord, activez l'option et ouvrez le compte :
option "account_rounding" "Equity:RoundingError"
2000-01-01 open Equity:RoundingError
Désormais, Beancount ajoutera automatiquement une troisième ligne à toute transaction qui ne s'équilibre pas dans sa tolérance, en imputant la différence à Equity:RoundingError.
2013-02-23 * "Achat"
Assets:Invest 1.245 RGAGX {43.23 USD}
Assets:Cash -53.82 USD
Dans cette transaction, . La transaction est déséquilibrée de USD. Avec l'option d'arrondi activée, Beancount la traite en interne comme :
2013-02-23 * "Achat"
Assets:Invest 1.245 RGAGX {43.23 USD}
Assets:Cash -53.82 USD
Equity:RoundingError -0.00135 USD ; Ajouté automatiquement
Précision numérique inférée
Beancount peut également utiliser les paramètres de tolérance pour arrondir automatiquement les nombres avant même qu'ils ne soient insérés dans les structures de données du livre.
-
Aucune tolérance spécifiée : Si aucune tolérance n'est définie, les nombres sont utilisés à leur pleine précision. Aucun arrondi ne se produit.
-
Avec tolérance par défaut : Si vous définissez une tolérance par défaut, les nombres seront quantifiés à ce niveau.
option "default_tolerance" "USD:0.001"Avec ce paramètre, un nombre comme
53.82135 USDserait arrondi et stocké sous la forme53.821 USD. -
Avec compte d'arrondi : Si à la fois une tolérance par défaut et un compte d'arrondi sont actifs, Beancount quantifie le nombre et capture le résiduel.
option "default_tolerance" "USD:0.01"
option "account_rounding" "Equity:RoundingError"Un nombre comme
53.82135 USDserait stocké sous la forme53.82 USD, et le résiduel de-0.00135 USDserait imputé àEquity:RoundingError.
Détails de l'implémentation
Quelques points techniques clarifient comment Beancount atteint cette fiabilité.
-
Représentation des nombres : Beancount utilise le module
decimalde Python, pas les nombres à virgule flottante. Cela permet d'obtenir jusqu'à 28 décimales de précision et d'éviter les erreurs de représentation binaire courantes aux nombres flottants. -
Classe DisplayContext : Cette classe interne gère tout le formatage des nombres à des fins d'affichage. Elle respecte les paramètres de précision spécifiques à la devise et peut formater la sortie avec des colonnes et des virgules alignées.
-
Précision vs. Tolérance : Il est essentiel de distinguer ces deux concepts :
- La précision concerne le format d'affichage d'un nombre (combien de décimales sont affichées).
- La tolérance est la marge d'erreur autorisée utilisée lors des contrôles de vérification.
Bonnes pratiques ✨
Voici quelques recommandations pratiques pour gérer la précision dans votre grand livre.
Configuration initiale
Pour la plupart des nouveaux grands livres, il s'agit d'une configuration de départ robuste :
; Une valeur par défaut raisonnable pour la plupart des devises (par exemple, USD, EUR)
option "inferred_tolerance_default" "*:0.005"
; Une marge de 10 % sur toutes les tolérances inférées
option "inferred_tolerance_multiplier" "1.1"
; Un compte pour récupérer toutes les poussières d'arrondi
option "account_rounding" "Equity:RoundingError"
2000-01-01 open Equity:RoundingError
Conseils de dépannage
Si vous rencontrez des erreurs d'équilibrage :
- Ajoutez des décimales au montant d'une écriture pour créer une inférence de tolérance locale plus précise.
- Utilisez des tolérances explicites (
~) sur les assertionsbalancequi échouent en raison d'écarts prévisibles. - Suivez les erreurs d'arrondi dans un compte dédié pour voir où et à quelle fréquence elles se produisent.
- Envisagez de définir des valeurs par défaut spécifiques à la devise si vous traitez fréquemment des devises qui ont des conventions différentes (par exemple, le JPY n'a pas de décimales).
Stratégie de migration
Lors de l'application de ces concepts à un grand livre existant et désordonné :
- Commencez par une tolérance globale généreuse (par exemple,
*:0.05) et un multiplicateur élevé pour que le fichier soit validé. - Réduisez progressivement les tolérances et corrigez les erreurs qui apparaissent.
- Ajoutez des chiffres explicites aux montants des transactions problématiques pour laisser l'inférence faire son travail.
- Surveillez le solde du compte d'arrondi. Un solde important ou à croissance rapide peut signaler un problème systémique qui nécessite une enquête.