Aller au contenu principal

Gestion des stocks

Apprenez à gérer efficacement les stocks dans Beancount, en vous concentrant sur le suivi des actifs comme les actions et les devises, la compréhension du coût de base et le calcul des gains en capital pour une meilleure performance de portefeuille.

Le système d'inventaire de Beancount est une fonctionnalité puissante pour suivre les actifs achetés et vendus au fil du temps, tels que les actions, les fonds communs de placement ou les devises étrangères. Il permet un suivi précis du coût d'acquisition, ce qui est essentiel pour calculer les plus-values et comprendre la performance du portefeuille. Ce tutoriel couvre les mécanismes essentiels de la gestion des inventaires dans votre registre.

Concepts fondamentaux

Au cœur du système de gestion des stocks se trouve le suivi des positions. Une « position » est simplement une quantité d'une marchandise détenue dans un compte. Beancount distingue deux types fondamentaux de positions.

Types de positions

  1. Position simple (sans coût) : Il s'agit d'une écriture de solde standard. Elle représente une quantité d'une marchandise sans aucun coût d'acquisition associé. Elle convient pour les liquidités ou de simples assertions de solde.

    Assets:Bank:Checking      100.00 USD
  2. Position avec coût d'acquisition : Ce type de position inclut non seulement le nombre d'unités et la marchandise, mais aussi le coût auquel elle a été acquise. C'est la base du suivi d'inventaire. Le coût est spécifié entre accolades {}.

    Assets:Invest:VTSAX      10 VTSAX {100.00 USD, "lot-1"}

    Dans cet exemple, nous détenons 10 unités de VTSAX. Chaque unité a été acquise au coût de 100,00 $ USD. Ce lot spécifique d'actions est identifié comme un « lot ».

Opérations sur l'inventaire

Il existe deux opérations principales que vous pouvez effectuer sur un inventaire :

  1. Augmentations (ajout à l'inventaire) : Lorsque vous achetez une marchandise, vous augmentez votre inventaire. Vous créez un nouveau lot avec un nombre spécifique d'unités et un coût d'acquisition.

    2024-01-15 * "Buy shares"
      Assets:Invest:STOCK     50 STOCK {25.00 USD, "lot-1"}
      Assets:Bank:Checking   -1250.00 USD

    Ici, nous achetons 50 unités de STOCK à un coût unitaire de 25,00 $ USD. Cela crée un lot dans le compte Assets:Invest:STOCK.

  2. Réductions (retrait de l'inventaire) : Lorsque vous vendez une marchandise, vous réduisez votre inventaire. Vous devez spécifier de quel lot vous vendez. Cela se fait en fournissant des informations correspondantes dans les accolades.

    2024-01-20 * "Sell shares"
      Assets:Invest:STOCK    -25 STOCK {25.00 USD}
      Assets:Bank:Checking    625.00 USD

    Dans cette transaction, nous vendons 25 unités de STOCK du lot qui a été acheté à 25,00 $ USD par unité.

Méthodes d'enregistrement

Lorsque vous réduisez un inventaire, Beancount a besoin d'une règle pour décider quel lot spécifique prélever si plusieurs lots correspondent à la réduction. Cette règle s'appelle la « méthode d'enregistrement ». Vous pouvez définir une valeur par défaut pour l'ensemble du fichier avec une option, ou donner à un compte sa propre méthode via la directive open.

Beancount 3.2.3 accepte sept noms de méthodes : STRICT (la valeur par défaut), STRICT_WITH_SIZE, NONE, FIFO, LIFO, HIFO et AVERAGE. Six d'entre elles sont implémentées ; AVERAGE analyse mais génère une erreur au moment où il doit comptabiliser une réduction, comme la section AVERAGE ci-dessous le montre.

1. STRICT (Par défaut)

La méthode STRICT est la méthode de comptabilisation par défaut et la plus sûre. Elle impose une correspondance explicite et non ambiguë.

2024-01-01 open Assets:Invest:STOCK "STRICT"
  • Exige une correspondance exacte du lot : le spécificateur de coût de l’écriture de réduction ({...}) doit identifier un seul lot — par coût, par date d’acquisition, par étiquette, ou par une quelconque combinaison de ceux-ci.
  • Erreurs sur correspondances ambiguës : si le spécificateur correspond à plusieurs lots, Beancount génère un AmbiguousMatchError au lieu de deviner.
  • Exception : si une réduction supprime exactement le nombre total d’unités correspondant au spécificateur, un spécificateur vide ({}) est autorisé, et la réduction est répartie sur ces lots.

Ce grand livre contient deux lots et en vend un en nommant son coût, ce qui est non ambigu :

1970-01-01 commodity STK
1970-01-01 open Assets:Broker:Strict  STK  "STRICT"
1970-01-01 open Assets:Broker:Cash    USD
1970-01-01 open Income:Gains          USD
 
2024-01-10 * "Buy the first lot"
  Assets:Broker:Strict    10 STK {100.00 USD}
  Assets:Broker:Cash   -1000.00 USD
 
2024-02-10 * "Buy the second lot"
  Assets:Broker:Strict    10 STK {120.00 USD}
  Assets:Broker:Cash   -1200.00 USD
 
; The cost identifies exactly one lot, so STRICT is satisfied.
2024-06-01 * "Sell the $120.00 lot"
  Assets:Broker:Strict   -10 STK {120.00 USD} @ 150.00 USD
  Assets:Broker:Cash    1500.00 USD
  Income:Gains

Il se charge sans erreurs, comptabilise un gain de 300,00 $ sur Income:Gains, et laisse 10 STK {100.00 USD} dans le compte.

Remplacez cette dernière écriture par un spécificateur vide et le même fichier échoue :

; Rejected under STRICT: "-10 STK {}" matches both lots.
2024-06-01 * "Sell 10 shares"
  Assets:Broker:Strict  -10 STK {} @ 150.00 USD
  Assets:Broker:Cash   1500.00 USD
  Income:Gains

Beancount signale Ambiguous matches for "-10 STK {}" et liste les candidats. Vendre la position entière est toutefois acceptable, car il ne reste rien parmi quoi choisir :

; Allowed under STRICT: -20 STK is the entire holding, so the empty
; specifier is split across both lots.
2024-06-01 * "Close the position"
  Assets:Broker:Strict  -20 STK {} @ 150.00 USD
  Assets:Broker:Cash   3000.00 USD
  Income:Gains

Cela comptabilise un gain de 800,00 $ — 3 000,00 $ de produit contre 1 000,00 $ + 1 200,00 $ de base — et laisse le compte vide. C’est une propriété intrinsèque de STRICT, pas une raison de passer à STRICT_WITH_SIZE.

2. FIFO (Premier Entré, Premier Sorti)

La méthode FIFO comptabilise automatiquement les réductions en commençant par les lots les plus anciens disponibles.

2024-01-01 open Assets:Invest:STOCK "FIFO"
  • Résolution automatique : elle résout l’ambiguïté en sélectionnant les lots correspondants les plus anciens.
  • Correspondance chronologique : on suppose que vous vendez les actifs que vous détenez depuis le plus longtemps. Plusieurs autorités fiscales considèrent cela comme la règle par défaut lorsque vous n’avez pas identifié un lot.

3. LIFO (Dernier Entré, Premier Sorti)

La méthode LIFO est l’opposée de FIFO. Elle comptabilise les réductions en commençant par les lots les plus récents disponibles.

2024-01-01 open Assets:Invest:STOCK "LIFO"
  • Ordre Chronologique Inverse : Il sélectionne les lots correspondants les plus récemment acquis.
  • Le plus récent, pas le plus cher : LIFO choisit uniquement en fonction de la date d'acquisition. Cela entraîne la vente des actions au coût le plus élevé lorsque les prix ont augmenté, mais si votre lot le plus récent est le moins cher — comme le montre l'exemple ci-dessous — LIFO réalisera le plus grand gain, pas le plus petit. La méthode qui vend toujours les actions les plus chères est HIFO, décrite ensuite.

4. HIFO (Highest-In, First-Out)

La méthode HIFO comptabilise d'abord les réductions sur les lots les plus chers disponibles, quelle que soit leur date.

2024-01-01 open Assets:Invest:STOCK "HIFO"
  • Appariement par Coût Classe : Elle sélectionne les lots correspondants avec la base de coût la plus élevée.
  • Gain Réalisé le Plus Petit : Pour un prix de vente donné, vendre les actions au coût le plus élevé réalise le gain le plus faible (ou la perte la plus importante). Son usage dépend de la juridiction — aux États-Unis, par exemple, choisir un lot nécessite une identification spécifique au moment de la vente — considérez donc cette méthode comme un mécanisme comptable et confirmez l'option fiscale séparément.

5. Comparaison de FIFO, LIFO et HIFO sur les mêmes lots

Les trois méthodes ne diffèrent que lorsque le lot le plus ancien, le plus récent et le plus cher sont trois lots différents. Ce grand livre organise précisément cela — le lot A est le plus ancien, le lot C est le plus récent, et le lot intermédiaire B est le plus cher — puis vend 10 actions à partir de trois comptes qui ne diffèrent que par leur méthode de comptabilisation :

1970-01-01 commodity STK
1970-01-01 open Assets:Broker:Fifo  STK  "FIFO"
1970-01-01 open Assets:Broker:Lifo  STK  "LIFO"
1970-01-01 open Assets:Broker:Hifo  STK  "HIFO"
1970-01-01 open Assets:Broker:Cash  USD
1970-01-01 open Income:Gains        USD
 
; Lot A - the oldest, at $100.00 per share
2024-01-10 * "Buy lot A"
  Assets:Broker:Fifo     10 STK {100.00 USD}
  Assets:Broker:Lifo     10 STK {100.00 USD}
  Assets:Broker:Hifo     10 STK {100.00 USD}
  Assets:Broker:Cash  -3000.00 USD
 
; Lot B - the most expensive, at $120.00 per share
2024-02-10 * "Buy lot B"
  Assets:Broker:Fifo     10 STK {120.00 USD}
  Assets:Broker:Lifo     10 STK {120.00 USD}
  Assets:Broker:Hifo     10 STK {120.00 USD}
  Assets:Broker:Cash  -3600.00 USD
 
; Lot C - the newest, at $90.00 per share
2024-03-10 * "Buy lot C"
  Assets:Broker:Fifo     10 STK {90.00 USD}
  Assets:Broker:Lifo     10 STK {90.00 USD}
  Assets:Broker:Hifo     10 STK {90.00 USD}
  Assets:Broker:Cash  -2700.00 USD
 
; Sell 10 shares out of each account at $150.00 and let each
; account's booking method choose which lot leaves.
2024-06-01 * "Sell 10 shares from each account"
  Assets:Broker:Fifo    -10 STK {} @ 150.00 USD
  Assets:Broker:Lifo    -10 STK {} @ 150.00 USD
  Assets:Broker:Hifo    -10 STK {} @ 150.00 USD
  Assets:Broker:Cash   4500.00 USD
  Income:Gains

Il se charge sans erreur et comptabilise un gain total de 1 400,00 $, réparti ainsi :

CompteMéthodeLot comptabiliséBase de coûtGain réaliséLots restants
Assets:Broker:FifoFIFOlot A, 2024-01-10100,00 $500,00 $10 à 120,00 $, 10 à 90,00 $
Assets:Broker:LifoLIFOlot C, 2024-03-1090,00 $600,00 $10 à 100,00 $, 10 à 120,00 $
Assets:Broker:HifoHIFOlot B, 2024-02-10120,00 $300,00 $10 à 100,00 $, 10 à 90,00 $

La ligne LIFO est celle qui mérite le plus d'attention : elle a réalisé le plus grand gain des trois, parce que le lot le plus récent était aussi le moins cher.

6. STRICT_WITH_SIZE

STRICT_WITH_SIZE est STRICT plus un critère de départage supplémentaire : lorsqu'un seul lot parmi plusieurs correspondants détient précisément le nombre d'unités que vous retirez, ce lot est choisi.

1970-01-01 commodity STK
1970-01-01 open Assets:Broker:Sized  STK  "STRICT_WITH_SIZE"
1970-01-01 open Assets:Broker:Cash   USD
1970-01-01 open Income:Gains         USD
 
2024-01-10 * "Buy 10 shares"
  Assets:Broker:Sized    10 STK {100.00 USD}
  Assets:Broker:Cash  -1000.00 USD
 
2024-02-10 * "Buy 7 shares"
  Assets:Broker:Sized     7 STK {120.00 USD}
  Assets:Broker:Cash   -840.00 USD
 
; Only one lot holds exactly 7 units, so the empty specifier resolves.
2024-06-01 * "Sell 7 shares"
  Assets:Broker:Sized    -7 STK {} @ 150.00 USD
  Assets:Broker:Cash   1050.00 USD
  Income:Gains

Cela enregistre un gain de 210,00 $ contre le lot de 120,00 $. Le fichier identique avec "STRICT" sur la ligne open échoue avec Ambiguous matches for "-7 STK {}".

7. MOYENNE (acceptée, mais non implémentée)

AVERAGE est un nom valide — option "booking_method" "AVERAGE" et open … "AVERAGE" sont tous les deux analysés — mais Beancount 3.2.3 ne possède pas d’implémentation derrière. Tout se charge ici jusqu’à la vente :

1970-01-01 commodity STK
1970-01-01 open Assets:Broker:Avg   STK  "AVERAGE"
1970-01-01 open Assets:Broker:Cash  USD
1970-01-01 open Income:Gains        USD
 
2024-01-10 * "Buy 10 shares at $10.00"
  Assets:Broker:Avg      10 STK {10.00 USD}
  Assets:Broker:Cash  -100.00 USD
 
2024-02-10 * "Buy 10 more at $8.00"
  Assets:Broker:Avg      10 STK {8.00 USD}
  Assets:Broker:Cash   -80.00 USD
 
; An average-cost engine would book this at $9.00 per share. This one refuses.
2024-06-01 * "Sell 5 shares"
  Assets:Broker:Avg      -5 STK {}
  Assets:Broker:Cash    45.00 USD
  Income:Gains

Au moment où cette réduction doit être enregistrée, le chargeur s’arrête avec :

AVERAGE method is not supported

Ne planifiez pas un grand livre autour de cela. Si vous souhaitez un comportement à coût moyen aujourd’hui, conservez la position dans un compte NONE et calculez la moyenne vous-même, ou suivez chaque lot et acceptez les gains au niveau des lots.

8. AUCUN

La méthode NONE désactive entièrement l’appariement des lots.

2024-01-01 open Assets:Invest:STOCK "NONE"
  • Pas d’appariement des lots : Beancount n’essaie pas d’apparier les réductions aux augmentations.
  • Autorise les signes mixtes : Cela permet à un compte de détenir simultanément des soldes positifs et négatifs de la même commodité. Ce comportement est similaire à celui de l’outil Ledger CLI pour gérer les commodités.

Spécification des lots

Un « lot » est un bloc spécifique d’une commodité acquis à un moment et à un prix particuliers. Lorsque vous créez ou réduisez une position, vous pouvez spécifier en détail ses attributs de lot.

Spécification complète

Lors de l’accroissement d’un inventaire (achat), vous pouvez spécifier jusqu’à trois attributs pour le lot, séparés par des virgules à l’intérieur d’une seule paire d’accolades :

Assets:Invest:STOCK  10 STOCK {100.00 USD, 2024-01-15, "lot-identifier"}
  • 100.00 USD — la base de coût, exprimée par unité.
  • 2024-01-15 — la date d’acquisition. Beancount la remplit à partir de la date de la transaction si vous l’omettez, ce pourquoi les messages d’erreur ci-dessus affichent une date sur chaque lot.
  • "lot-identifier" — une étiquette de chaîne optionnelle.

Bien que les trois soient optionnels, fournir au moins la base de coût est la pratique standard. Les accolades doivent rester sur une seule ligne, et les commentaires dans un grand livre commencent par ;, jamais #.

Méthodes d’appariement

Lors de la réduction d’un inventaire (vente), vous utilisez la même syntaxe pour spécifier de quel(s) lot(s) vous vendez.

  • Appariement par coût : C’est la méthode la plus courante.

    Assets:Invest:STOCK  -5 STOCK {100.00 USD}
  • Appariement par date : Si les coûts sont identiques, vous pouvez désambiguïser à l’aide de la date d’acquisition.

    Assets:Invest:STOCK  -5 STOCK {2024-01-15}
  • Appariement par étiquette : Les étiquettes fournissent un moyen sûr d’identifier un lot.

    Assets:Invest:STOCK  -5 STOCK {"lot-identifier"}
  • Laisser le lot à la méthode d’enregistrement : Une paire d’accolades vide {} ne désigne aucun lot, donc la méthode d’enregistrement du compte choisit. Sous FIFO, LIFO ou HIFO, c’est le lot apparié le plus ancien, le plus récent ou le plus cher ; sous la valeur par défaut STRICT, c’est un AmbiguousMatchError, sauf si la réduction vide exactement les lots appariés.

    Assets:Invest:STOCK  -5 STOCK {}

Gestion des prix

Il est crucial de comprendre la différence entre coût de base ({}) et prix (@). Ils ont des usages différents et ne sont pas interchangeables.

Prix vs Coût

  • {cost} : Définit le coût d'acquisition d'un actif. Il fait partie du lot d'inventaire lui-même et est utilisé pour enregistrer les réductions et calculer les plus-values.
  • @ price : Une annotation qui enregistre un prix du marché au moment d'une transaction. Il est utilisé pour les conversions de devises ou pour noter la valeur de marché à une date donnée.

Voici les trois scénarios :

  1. Annotation de prix (Conversion) : Utilisez @ pour convertir une devise en une autre.

    Assets:Forex     1000 USD @ 0.85 EUR
  2. Coût de base (Acquisition) : Utilisez {} lors de l'achat d'un actif pour établir son coût.

    Assets:Invest    10 STOCK {100.00 USD}
  3. Les deux (Vente avec enregistrement du prix) : Lors de la vente d'un actif, utilisez {} pour identifier le lot vendu et @ pour enregistrer le prix de vente. Cela permet un calcul automatisé des plus-values.

    Assets:Invest    -10 STOCK {100.00 USD} @ 105.00 USD

    Cette entrée vend 10 STOCK du lot qui coûtait 100,00 $ chacun, à un prix de vente de 105,00 $ chacun.

Règles d'utilisation du prix

  1. Les annotations de prix (@) n'affectent pas le lot qui est enregistré. L'appariement des lots est géré exclusivement par le coût de base ({}) et la méthode d'enregistrement du compte.
  2. Le symbole @ est utilisé uniquement pour :
  • Les conversions de devises.
  • L'enregistrement de la valeur de marché d'un actif au moment d'une transaction.
  • Fournir le prix de vente pour les calculs de plus-values.

Configuration

Vous pouvez configurer les méthodes d'enregistrement globalement ou par compte.

Méthode d'enregistrement globale

Vous pouvez définir une méthode d'enregistrement par défaut pour l'ensemble de votre fichier Beancount en utilisant la directive option.

option "booking_method" "STRICT"

Les valeurs acceptées sont "STRICT" (la valeur par défaut si aucune n'est définie), "STRICT_WITH_SIZE", "NONE", "FIFO", "LIFO", "HIFO" et "AVERAGE". Toute autre chaîne est rejetée au chargement avec Error for option 'booking_method'. "AVERAGE" est accepté ici et sur open, mais l'enregistrement d'une réduction sous celle-ci échoue, comme la section AVERAGE ci-dessus le montre.

Surcharge par compte

Il est souvent utile d'avoir différentes méthodes pour différents comptes. Par exemple, vous pourriez vouloir FIFO pour un compte de retraite mais STRICT pour un compte de courtage imposable afin de garantir la vente de lots fiscaux spécifiques. Vous pouvez définir la méthode d'enregistrement lors de l'ouverture du compte.

2024-01-01 open Assets:Retirement:401K "FIFO"
2024-01-01 open Assets:Taxable:Stock  "STRICT"

Meilleures pratiques

  1. Organisation de l'inventaire : Pour garder votre grand livre propre et simple, il est fortement recommandé d'utiliser des comptes distincts pour chaque marchandise unique que vous détenez, et de contraindre chacun à cette marchandise sur sa directive open.

    ; GOOD: separate accounts by commodity, each constrained to one
    2024-01-01 open Assets:Invest:VTSAX  VTSAX
    2024-01-01 open Assets:Invest:VFIAX  VFIAX

    Évitez de mélanger différentes actions ou fonds dans le même compte, car cela complique la gestion des inventaires. La liste des marchandises sur open fait en sorte que Beancount rejette une écriture errante au lieu de mélanger silencieusement deux inventaires.

  2. Gestion des lots :

  • Utilisez des étiquettes significatives pour les lots, en particulier pour les transactions spécifiques comme la récolte de pertes fiscales ou les attributions d’actions aux employés.

    Assets:Invest:STOCK  10 STOCK {100.00 USD, "tax-loss-harvest-2024"}
  • Documentez vos opérations avec des commentaires. Cela rend votre grand livre plus facile à lire et à comprendre par la suite.

    Assets:Invest:STOCK  -10 STOCK {100.00 USD} @ 110.00 USD ; Gain: 10%
  1. Débogage : Si vous rencontrez des erreurs ou un comportement inattendu, Beancount fournit des outils pour inspecter l’état de votre inventaire.
  • Examinez l’état de l’inventaire : Utilisez bea doctor context main.beancount 42 pour inspecter la transaction à la ligne 42, y compris ses écritures et les soldes des comptes affectés. Remplacez le nom du fichier et le numéro de ligne par la transaction que vous souhaitez examiner.

    Remplacez <LINENO> par le numéro de ligne juste après une transaction pour voir son effet.

  • Vérifiez l’appariement des lots : L’outil bea check valide votre fichier entier. Il détectera toute erreur d’écriture, comme des correspondances ambiguës de lots en mode STRICT.

Source : https://beancount.io/fr/docs/Basics/inventories