Principes d’ingénierie pour construire des systèmes financiers
(substack.wasteman.codes)- La comptabilité a très peu changé au cours des derniers siècles
- Malgré cela, il existe beaucoup de confusion sur la bonne manière de construire des logiciels pour les systèmes financiers
- Cet article partage des enseignements tirés de l’expérience de construction de systèmes financiers dans de grandes entreprises
- Même si l’accent est mis sur la construction de systèmes comptables, ces principes s’appliquent aussi à des systèmes financiers plus généraux
Définition des termes financiers de base
- Grand livre (General Ledger, GL) : principal registre comptable d’une entreprise, qui résume toutes les transactions financières sur une période donnée. On peut le considérer comme l’agrégation des sous-livres correspondants
- Sous-livre (Sub-ledger) : contient les détails de chaque transaction individuelle liée à un GL donné. Les enregistrements d’un sous-livre contiennent des données bien plus granulaires que le grand livre (par ex. un client précis, une ligne précise d’une commande, etc.). L’écart de données entre un sous-livre et le GL varie selon le type d’activité et le volume de données traité. Certaines petites entreprises peuvent fonctionner sans sous-livre, mais à petite échelle il est peu probable qu’un logiciel sur mesure soit nécessaire
- Enregistrements financiers (Financial Record) : terme générique désignant le grand livre et les sous-livres
- Caractère significatif (Material) : indique si une information erronée dans les états financiers est susceptible d’influencer la décision d’une partie prenante raisonnable. Cette définition est volontairement un peu floue, car les critères de significativité diffèrent selon les entreprises. Par exemple, ce qui est significatif pour une entreprise réalisant 250 k$ de chiffre d’affaires annuel peut ne pas l’être pour une entreprise à 1 Md$ de chiffre d’affaires annuel. Du point de vue de la conception, la principale utilité de ce concept est de classer différentes catégories de données financières
High Level Data Flow
Business System --(Financial Events)--> Sub Ledger(s) --(Summarized Accounting Entries)--> General Ledger
Les trois objectifs principaux d’un système comptable
- Exactitude (Accurate) : les enregistrements financiers doivent refléter l’état connu de l’activité
- Exemple : si 10 produits à 9,99 $ ont été vendus, le total dans les enregistrements financiers doit être de 99,90 $
- Cela semble évident, mais lorsque l’on agrège des milliers ou des millions de transactions, de simples erreurs d’addition entre systèmes ou d’arrondi peuvent provoquer des inexactitudes significatives
-
Note de Wasteman
- On dit souvent que le naming est le problème le plus difficile en informatique, mais je pense que l’addition arrive juste après
- En travaillant ces dernières années sur de grands systèmes financiers, j’ai vu d’innombrables cas où un bug minuscule provoquait un écart énorme dans les données
- Ne parlons même pas des sommes sur des
float. J’ai appris à mes dépens pourquoi il faut toujours utiliser des entiers
- Les enregistrements financiers doivent être complets (complete)
- Plus précisément, les sous-livres et le grand livre doivent représenter intégralement toute l’activité métier survenue à un instant donné
- Si un événement s’est produit mais n’apparaît pas dans les enregistrements financiers, alors le système n’est pas complet
- Cela ne signifie pas que la cohérence à terme (eventual consistency) est interdite
- Il faut savoir à quel moment les données seront complètes afin de pouvoir indiquer aux parties prenantes qu’elles sont finalisées
-
Note de Wasteman
- Garantir l’exhaustivité est aussi un problème étonnamment difficile
- À mesure qu’un système grossit, les données peuvent être accidentellement modifiées ou perdues en transitant entre plusieurs systèmes
- Auditabilité (Auditable) : les enregistrements financiers doivent pouvoir être audités facilement afin que les parties prenantes puissent détecter les erreurs et mesurer précisément les performances de l’activité
- Ponctualité (Timely) : le système comptable doit répondre aux besoins spécifiques de l’entreprise
- Pour une petite entreprise, il peut suffire de déverser tous les chiffres en fin de mois, mais les grandes entreprises veulent généralement des systèmes quasi temps réel
- Cela permet de surveiller la santé financière tout au long du mois, de prendre plus rapidement des décisions fondées sur les données financières, et de réduire la pression liée aux clôtures en début de mois ou de trimestre
- Quels que soient les besoins, notre système comptable doit répondre aux exigences de l’entreprise, selon ce que ponctuel signifie pour elle
-
Note de Wasteman
- Les gens ont tendance à se perdre dans les débats batch vs streaming quand on parle de ponctualité
- À mon avis, dans la plupart des systèmes, ce n’est pas une distinction importante
- Cela compte si l’on se soucie de latences très courtes, de l’ordre de la seconde à la minute
- Mais il est étonnamment fréquent d’entendre des gens débattre de ce qu’il faut faire alors que les consommateurs n’ont pas besoin de voir des mises à jour plus de quelques fois par jour
- Ce n’est pas parce qu’on l’a demandé que c’est forcément nécessaire
Les trois grands principes d’ingénierie qu’un système comptable doit respecter
- Immutabilité (Immutability) et durabilité (Durability) des données
- Elles permettent l’auditabilité, ce qui aide au débogage et à l’exactitude
- Si les données sont immuables, on peut enregistrer l’état du système à n’importe quel moment
- Cela rend très facile le recalcul du monde à partir d’un état antérieur, puisqu’aucun état n’est perdu
- Une fois que des données sont inscrites dans les enregistrements financiers, elles ne peuvent pas être supprimées
- Toute correction apportée au système doit être représentée comme une nouvelle transaction financière
- Exemple : s’il y a un bug dans le système et qu’un service qui aurait dû être vendu 900 $ a été enregistré par erreur comme vendu 1 000 $
- Pour corriger cette erreur, il faut d’abord annuler l’écriture comptable correspondant à l’erreur, puis réécrire l’écriture comptable avec le montant exact
- Les données doivent être enregistrées au niveau de granularité le plus fin (Data recorded at the smallest grain)
- Comme le principe ci-dessus, c’est aussi crucial pour permettre une piste d’audit claire
- Même si les rapports financiers et le grand livre sont agrégés, ils sont calculés à partir d’événements plus granulaires
- Quand les données ne sont pas comprises, il faut les données les plus fines pour déboguer le problème
- Stocker les données au niveau de granularité le plus bas facilite aussi énormément la correction des données dérivées de ce jeu de données
- Si un jeu de données immuable unique est la source de vérité centrale pour toutes les vues de ces données,
- corriger une vue revient simplement à corriger les données puis à relancer le pipeline qui génère cette vue
- De même, lorsqu’un comptable se prépare à clôturer les livres,
- il rapproche toutes les transactions survenues et les soldes des comptes afin de vérifier que les livres sont exacts
- si un écart est détecté, il peut remonter jusqu’à la transaction précise à l’origine du problème
- Le système doit être idempotent (Idempotency)
- Chaque événement financier ne doit être traité qu’une seule fois, et les doublons dans les enregistrements financiers créeraient des inexactitudes évidentes
- Pour cette raison, tout le code qui génère des enregistrements financiers doit être idempotent
- L’idempotence est la propriété selon laquelle appliquer plusieurs fois une opération ne change pas le résultat
- Autrement dit, même si un événement financier est traité plusieurs fois, le résultat doit être identique à celui du premier traitement
Bonnes pratiques
- Privilégier les entiers pour représenter les montants financiers : les opérations arithmétiques deviennent beaucoup plus simples. Éviter les
float - Prendre en charge une granularité des montants financiers qui minimise la perte de précision lors des conversions de devises
- Si vous ne traitez que des dollars, une représentation en cents peut suffire
- Pour une activité mondiale, préférer des micro-unités ou des nombres décimaux comme
DECIMAL(19, 4) - L’usage des décimaux est populaire dans les systèmes financiers, mais dans les systèmes financiers publicitaires, les micro-unités sont la norme
- Utiliser une méthode d’arrondi cohérente : selon la méthode d’arrondi, des écarts notables peuvent apparaître par rapport au montant attendu
- Arrondir toute valeur de 5 ou plus au chiffre significatif suivant, et toute valeur de 4 ou moins à l’inférieur
- Ou encore toujours arrondir à l’entier supérieur
- L’important est de rester cohérent partout (si l’écart est de 1 centime par transaction, sur 10 millions de transactions cela fait 100 k$ d’écart)
- Retarder autant que possible les conversions de devises : convertir trop tôt peut entraîner une perte de précision
- Reporter la conversion jusqu’après l’agrégation dans la devise locale
- Utiliser une représentation entière du temps : c’est légèrement controversé, mais fortement recommandé
- Différentes bibliothèques qui parsèrent les timestamps en objets les traitent chacune différemment
- Mieux vaut éviter ce casse-tête et utiliser des entiers
- Les timestamps Unix ou des datetime entiers basés sur UTC fonctionnent très bien
- Moins il y a de transformations de données entre systèmes, mieux c’est
-
Note de Wasteman
- Je n’ai même pas parlé des bugs liés à l’heure d’été. Utiliser des entiers croissants permet de les éviter complètement
- Si vous tenez absolument à utiliser des datetime, utilisez au moins UTC. Il est étonnamment fréquent que de très grandes entreprises utilisent des timestamps qui ne sont pas en UTC
2 commentaires
C’est vraiment très utile. Si on fait sans réfléchir des conversions de type (
decimal,float,double) ou des arrondis, sans en discuter en amont avec les équipes métier, ça peut avoir de très graves conséquences.Commentaires sur Hacker News
Insistance sur l’importance d’utiliser une méthodologie d’arrondi cohérente
Recommandation de représenter le temps sous forme d’entier
Recommandation d’utiliser une base de données relationnelle pour les systèmes comptables
Les principaux objectifs d’un système comptable sont l’exactitude, l’auditabilité et la ponctualité
Avis sur l’exhaustivité des systèmes comptables
Pour une activité mondiale, recommandation d’utiliser au minimum 8 décimales
Mention de l’importance de l’interface utilisateur (UI)
Explication de la différence entre traitement par lots et traitement en streaming
Partage d’expérience sur la création d’un système de facturation avec TypeScript
Recommandation d’utiliser les classes de la bibliothèque standard
BigDecimalen Java et deDecimalen PythonExplication des difficultés liées à l’arrondi et au partage de données
Partage d’expérience sur le travail avec les API des 10 plus grandes banques américaines
Recommandation de "Accounting Patterns" de Martin Fowler