Beancounts Bestandssystem ist eine leistungsstarke Funktion zur Verfolgung von Vermögenswerten, die über die Zeit gekauft und verkauft werden, wie Aktien, Investmentfonds oder Fremdwährungen. Es ermöglicht eine präzise Verfolgung der Anschaffungskosten, was für die Berechnung von Kapitalgewinnen und das Verständnis der Portfolio-Performance unerlässlich ist. Dieses Tutorial behandelt die Kernmechanismen der Bestandsverwaltung in Ihrem Ledger.
Grundlegende Konzepte
Im Kern dreht sich die Bestandsverwaltung um die Verfolgung von Positionen. Eine „Position" ist einfach eine Menge eines Rohstoffs, die in einem Konto gehalten wird. Beancount unterscheidet zwischen zwei grundlegenden Arten von Positionen.
Positionstypen
-
Einfache Position (ohne Kosten): Dies ist eine Standard-Saldenbuchung. Sie repräsentiert eine Menge eines Rohstoffs ohne zugehörige Anschaffungskosten. Sie eignet sich für Bargeld oder einfache Saldenprüfungen.
Assets:Bank:Checking 100.00 USD -
Position mit Anschaffungskosten: Diese Art von Position umfasst nicht nur die Anzahl der Einheiten und den Rohstoff, sondern auch die Kosten, zu denen sie erworben wurde. Dies ist die Grundlage der Bestandsverfolgung. Die Kosten werden in geschweiften Klammern
{}angegeben.Assets:Invest:VTSAX 10 VTSAX {100.00 USD, "lot-1"}In diesem Beispiel halten wir 10 Einheiten von
VTSAX. Jede Einheit wurde zu einem Preis von 100,00 USD erworben. Diese spezifische Charge von Anteilen wird als „Lot" bezeichnet.
Bestandsoperationen
Es gibt zwei primäre Operationen, die Sie an einem Bestand durchführen können:
-
Erhöhungen (Hinzufügen zum Bestand): Wenn Sie einen Rohstoff kaufen, erhöhen Sie Ihren Bestand. Sie erstellen ein neues Lot mit einer bestimmten Anzahl von Einheiten und Anschaffungskosten.
2024-01-15 * "Buy shares" Assets:Invest:STOCK 50 STOCK {25.00 USD, "lot-1"} Assets:Bank:Checking -1250.00 USDHier kaufen wir 50 Einheiten von
STOCKzu einem Stückpreis von 25,00 USD. Dies erstellt ein Lot im KontoAssets:Invest:STOCK. -
Reduzierungen (Entfernen aus dem Bestand): Wenn Sie einen Rohstoff verkaufen, reduzieren Sie Ihren Bestand. Sie müssen angeben, aus welchem Lot Sie verkaufen. Dies geschieht durch die Angabe übereinstimmender Informationen in den geschweiften Klammern.
2024-01-20 * "Sell shares" Assets:Invest:STOCK -25 STOCK {25.00 USD} Assets:Bank:Checking 625.00 USDIn dieser Transaktion verkaufen wir 25 Einheiten von
STOCKaus dem Lot, das zu 25,00 USD pro Einheit gekauft wurde.
Buchungsmethoden
Wenn Sie einen Bestand reduzieren, benötigt Beancount eine Regel, um zu entscheiden, aus welchem spezifischen Lot entnommen werden soll, wenn mehrere Lots mit der Reduzierung übereinstimmen. Diese Regel wird „Buchungsmethode" genannt. Sie können eine Standardmethode für die gesamte Datei mit einer Option festlegen oder einem Konto eine eigene Methode in der open-Direktive zuweisen.
Beancount 3.2.3 akzeptiert sieben Methodennamen: STRICT (der Standard), STRICT_WITH_SIZE, NONE, FIFO, LIFO, HIFO und AVERAGE. Sechs davon sind implementiert; AVERAGE wird geparst, wirft aber einen Fehler, sobald eine Reduzierung gebucht werden muss, wie der Abschnitt AVERAGE unten zeigt.
1. STRICT (Standard)
Die STRICT-Methode ist der Standard und die sicherste Buchungsmethode. Sie erzwingt eine explizite und eindeutige Zuordnung.
2024-01-01 open Assets:Invest:STOCK "STRICT"- Erfordert exakte Lot-Übereinstimmung: Der Kostenbezeichner (
{...}) der Reduzierungsbuchung muss ein einzelnes Lot identifizieren — anhand der Kosten, des Erwerbsdatums, des Labels oder einer beliebigen Kombination davon. - Fehler bei mehrdeutigen Übereinstimmungen: Wenn der Bezeichner mit mehr als einem Lot übereinstimmt, wirft Beancount einen
AmbiguousMatchError, anstatt zu raten. - Ausnahme: Wenn eine Reduzierung genau die Gesamtzahl der Einheiten entfernt, mit denen der Bezeichner übereinstimmt, ist ein leerer Bezeichner (
{}) erlaubt, und die Reduzierung wird auf diese Lots aufgeteilt.
Dieses Ledger enthält zwei Lots und verkauft eines davon durch Angabe seiner Kosten, was eindeutig ist:
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:GainsEs lädt ohne Fehler, bucht 300,00 USD Gewinn auf Income:Gains und lässt 10 STK {100.00 USD} im Konto zurück.
Ersetzen Sie diese letzte Buchung durch einen leeren Bezeichner, und dieselbe Datei schlägt fehl:
; 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:GainsBeancount meldet Ambiguous matches for "-10 STK {}" und listet die Kandidaten auf. Die gesamte Position zu verkaufen ist jedoch in Ordnung, da nichts mehr zur Auswahl steht:
; 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:GainsDas bucht 800,00 USD Gewinn — 3.000,00 USD Erlös gegen 1.000,00 USD + 1.200,00 USD Anschaffungskosten — und lässt das Konto leer. Dies ist eine Eigenschaft von STRICT selbst, nichts, wofür Sie zu STRICT_WITH_SIZE wechseln müssten.
2. FIFO (First-In, First-Out)
Die FIFO-Methode bucht Reduzierungen automatisch gegen die ältesten verfügbaren Lots zuerst.
2024-01-01 open Assets:Invest:STOCK "FIFO"- Automatische Auflösung: Sie löst Mehrdeutigkeiten auf, indem sie die ältesten übereinstimmenden Lots auswählt.
- Chronologische Zuordnung: Sie gehen davon aus, dass Sie die Vermögenswerte verkaufen, die Sie am längsten gehalten haben. Mehrere Steuerbehörden behandeln dies als Standard, wenn Sie kein Lot identifiziert haben.
3. LIFO (Last-In, First-Out)
Die LIFO-Methode ist das Gegenteil von FIFO. Sie bucht Reduzierungen gegen die neuesten verfügbaren Lots zuerst.
2024-01-01 open Assets:Invest:STOCK "LIFO"- Umgekehrte chronologische Reihenfolge: Sie wählt die zuletzt erworbenen übereinstimmenden Lots aus.
- Neueste, nicht teuerste: LIFO wählt nur nach Erwerbsdatum. Es verkauft zufällig die teuersten Anteile, wenn die Preise gestiegen sind, aber wenn Ihr neuestes Lot Ihr günstigstes ist — was das folgende Beispiel zeigen soll —, realisiert LIFO den größten Gewinn, nicht den kleinsten. Die Methode, die immer die teuersten Anteile verkauft, ist
HIFO, die als Nächstes beschrieben wird.
4. HIFO (Highest-In, First-Out)
Die HIFO-Methode bucht Reduzierungen gegen die teuersten verfügbaren Lots zuerst, unabhängig von ihrem Datum.
2024-01-01 open Assets:Invest:STOCK "HIFO"- Nach Kosten gereihte Zuordnung: Sie wählt die übereinstimmenden Lots mit den höchsten Anschaffungskosten aus.
- Kleinster realisierter Gewinn: Bei einem gegebenen Verkaufspreis realisiert der Verkauf der teuersten Anteile den kleinsten Gewinn (oder den größten Verlust). Ob Sie dies verwenden dürfen, ist eine Frage der Rechtsordnung — in den Vereinigten Staaten beispielsweise erfordert die Auswahl eines Lots überhaupt eine spezifische Identifikation zum Zeitpunkt des Verkaufs —, behandeln Sie die Methode also als Buchhaltungsmechanismus und bestätigen Sie die Steuerwahl separat.
5. Vergleich von FIFO, LIFO und HIFO bei denselben Losen
Die drei Methoden unterscheiden sich nur, wenn das älteste, das neueste und das teuerste Lot drei verschiedene Lots sind. Dieses Ledger arrangiert genau das — Lot A ist das älteste, Lot C ist das neueste, und das mittlere Lot B ist das teuerste — und verkauft dann 10 Anteile aus drei Konten, die sich nur in ihrer Buchungsmethode unterscheiden:
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:GainsEs lädt ohne Fehler und bucht insgesamt 1.400,00 USD Gewinn, aufgeteilt wie folgt:
| Konto | Methode | Gebuchtes Lot | Anschaffungskosten | Realisierter Gewinn | Verbleibende Lots |
|---|---|---|---|---|---|
Assets:Broker:Fifo | FIFO | Lot A, 2024-01-10 | 100,00 USD | 500,00 USD | 10 @ 120,00 USD, 10 @ 90,00 USD |
Assets:Broker:Lifo | LIFO | Lot C, 2024-03-10 | 90,00 USD | 600,00 USD | 10 @ 100,00 USD, 10 @ 120,00 USD |
Assets:Broker:Hifo | HIFO | Lot B, 2024-02-10 | 120,00 USD | 300,00 USD | 10 @ 100,00 USD, 10 @ 90,00 USD |
Die LIFO-Zeile ist die, die es wert ist, genau betrachtet zu werden: Sie realisierte den größten Gewinn der drei, weil das neueste Lot auch das günstigste war.
6. STRICT_WITH_SIZE
STRICT_WITH_SIZE ist STRICT plus ein zusätzlicher Tie-Breaker: Wenn mehrere Lots übereinstimmen, aber genau eines davon präzise die Anzahl der Einheiten enthält, die Sie entfernen, wird dieses Lot gewählt.
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:GainsDas bucht 210,00 USD Gewinn gegen das 120,00-USD-Lot. Die identische Datei mit "STRICT" in der open-Zeile schlägt fehl mit Ambiguous matches for "-7 STK {}".
7. DURCHSCHNITT (akzeptiert, aber nicht implementiert)
AVERAGE ist ein gültiger Name — option "booking_method" "AVERAGE" und open … "AVERAGE" werden beide geparst —, aber Beancount 3.2.3 hat keine Implementierung dahinter. Alles hier lädt bis zum Verkauf:
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:GainsSobald diese Reduzierung gebucht werden muss, stoppt der Loader mit:
AVERAGE method is not supportedPlanen Sie kein Ledger darum herum. Wenn Sie heute Durchschnittskostenverhalten wünschen, halten Sie die Position in einem NONE-Konto und berechnen Sie den Durchschnitt selbst, oder verfolgen Sie jedes Lot und akzeptieren Sie Gewinne auf Lot-Ebene.
8. KEINER
Die NONE-Methode deaktiviert die Lot-Zuordnung vollständig.
2024-01-01 open Assets:Invest:STOCK "NONE"- Keine Lot-Zuordnung: Beancount versucht nicht, Reduzierungen mit Erhöhungen abzugleichen.
- Erlaubt gemischte Vorzeichen: Dies erlaubt einem Konto, gleichzeitig sowohl positive als auch negative Salden desselben Rohstoffs zu halten. Dieses Verhalten ähnelt der Art und Weise, wie das Ledger-CLI-Tool Rohstoffe behandelt.
Los-Spezifikation
Ein „Lot" ist ein spezifischer Block eines Rohstoffs, der zu einem bestimmten Zeitpunkt und Preis erworben wurde. Wenn Sie eine Position erstellen oder reduzieren, können Sie ihre Lot-Attribute im Detail angeben.
Vollständige Spezifikation
Beim Erhöhen eines Bestands (Kaufen) können Sie bis zu drei Attribute für das Lot angeben, kommagetrennt innerhalb eines einzelnen Klammerpaars:
Assets:Invest:STOCK 10 STOCK {100.00 USD, 2024-01-15, "lot-identifier"}100.00 USD— die Anschaffungskosten, ausgedrückt pro Einheit.2024-01-15— das Erwerbsdatum. Beancount füllt dieses aus dem Transaktionsdatum ein, wenn Sie es weglassen, weshalb die obigen Fehlermeldungen ein Datum bei jedem Lot anzeigen."lot-identifier"— ein optionales String-Label.
Obwohl alle drei optional sind, ist die Angabe mindestens der Anschaffungskosten Standardpraxis. Die Klammern müssen in einer Zeile bleiben, und Kommentare innerhalb eines Ledgers beginnen mit ;, niemals mit #.
Zuordnungs-Methoden
Beim Reduzieren eines Bestands (Verkaufen) verwenden Sie dieselbe Syntax, um anzugeben, aus welchem Lot bzw. welchen Lots verkauft werden soll.
-
Zuordnung nach Kosten: Dies ist die gebräuchlichste Methode.
Assets:Invest:STOCK -5 STOCK {100.00 USD} -
Zuordnung nach Datum: Wenn die Kosten identisch sind, können Sie mithilfe des Erwerbsdatums eindeutig zuordnen.
Assets:Invest:STOCK -5 STOCK {2024-01-15} -
Zuordnung nach Label: Labels bieten eine narrensichere Möglichkeit, ein Lot zu identifizieren.
Assets:Invest:STOCK -5 STOCK {"lot-identifier"} -
Das Lot der Buchungsmethode überlassen: Ein leeres Klammerpaar
{}benennt kein Lot, sodass die Buchungsmethode des Kontos wählt. UnterFIFO,LIFOoderHIFOist das das älteste, neueste oder teuerste übereinstimmende Lot; unter dem StandardSTRICTist es einAmbiguousMatchError, es sei denn, die Reduzierung leert die übereinstimmenden Lots genau.Assets:Invest:STOCK -5 STOCK {}
Preisbehandlung
Es ist entscheidend, den Unterschied zwischen Anschaffungskosten ({}) und Preis (@) zu verstehen. Sie dienen unterschiedlichen Zwecken und sind nicht austauschbar.
Preis vs Kosten
{cost}: Definiert die Anschaffungskosten eines Vermögenswerts. Es ist Teil des Bestandslots selbst und wird zur Buchung von Reduzierungen und zur Berechnung von Kapitalgewinnen verwendet.@ price: Eine Annotation, die einen Marktpreis zum Zeitpunkt einer Transaktion erfasst. Sie wird für Währungsumrechnungen oder zur Notierung des Marktwerts zu einem bestimmten Datum verwendet.
Hier sind die drei Szenarien:
-
Preisannotation (Umrechnung): Verwenden Sie
@, um von einer Währung in eine andere umzurechnen.Assets:Forex 1000 USD @ 0.85 EUR -
Anschaffungskosten (Erwerb): Verwenden Sie
{}beim Kauf eines Vermögenswerts, um seine Kosten festzulegen.Assets:Invest 10 STOCK {100.00 USD} -
Beides (Verkauf mit Preisaufzeichnung): Verwenden Sie beim Verkauf eines Vermögenswerts
{}, um das verkaufte Lot zu identifizieren, und@, um den Verkaufspreis aufzuzeichnen. Dies ermöglicht eine automatisierte Berechnung von Kapitalgewinnen.Assets:Invest -10 STOCK {100.00 USD} @ 105.00 USDDieser Eintrag verkauft 10
STOCKaus dem Lot, das 100,00 USD pro Stück gekostet hat, zu einem Verkaufspreis von 105,00 USD pro Stück.
Eine eigenständige price-Direktive liefert Referenzdaten für die Marktbewertung. Live-Preise können diese Direktiven für unterstützte Vermögenswerte in gehosteten Ledgers pflegen. Eine Aktualisierung lässt Ihre Lots, Buchungsmethode, Anschaffungskosten und aufgezeichneten Verkaufserlöse unverändert.
Regeln für die Preisverwendung
- Preisannotationen (
@) beeinflussen nicht, welches Lot gebucht wird. Die Lot-Zuordnung wird ausschließlich durch die Anschaffungskosten ({}) und die Buchungsmethode des Kontos geregelt. - Das Symbol
@wird nur verwendet für:
- Währungsumrechnungen.
- Die Aufzeichnung des Marktwerts eines Vermögenswerts zum Zeitpunkt einer Transaktion.
- Die Bereitstellung des Verkaufspreises für Kapitalgewinnberechnungen.
Konfiguration
Sie können Buchungsmethoden global oder pro Konto konfigurieren.
Globale Buchungsmethode
Sie können eine Standard-Buchungsmethode für Ihre gesamte Beancount-Datei mit der option-Direktive festlegen.
option "booking_method" "STRICT"Die akzeptierten Werte sind "STRICT" (der Standard, wenn Sie nichts festlegen), "STRICT_WITH_SIZE", "NONE", "FIFO", "LIFO", "HIFO" und "AVERAGE". Jede andere Zeichenkette wird beim Laden mit Error for option 'booking_method' abgelehnt. "AVERAGE" wird hier und bei open akzeptiert, aber das Buchen einer Reduzierung darunter schlägt fehl, wie der Abschnitt AVERAGE oben zeigt.
Kontoabhängige Überschreibung
Es ist oft nützlich, unterschiedliche Methoden für unterschiedliche Konten zu haben. Zum Beispiel möchten Sie vielleicht FIFO für ein Altersvorsorgekonto, aber STRICT für ein steuerpflichtiges Brokerkonto, um sicherzustellen, dass Sie bestimmte Steuer-Lots verkaufen. Sie können die Buchungsmethode beim Eröffnen des Kontos festlegen.
2024-01-01 open Assets:Retirement:401K "FIFO"
2024-01-01 open Assets:Taxable:Stock "STRICT"Best Practices
-
Bestandsorganisation: Um Ihr Ledger sauber und einfach zu halten, wird dringend empfohlen, separate Konten für jeden einzelnen Rohstoff zu verwenden, den Sie halten, und jedes davon in seiner
open-Direktive auf diesen Rohstoff zu beschränken.; GOOD: separate accounts by commodity, each constrained to one 2024-01-01 open Assets:Invest:VTSAX VTSAX 2024-01-01 open Assets:Invest:VFIAX VFIAXVermeiden Sie es, verschiedene Aktien oder Fonds im selben Konto zu mischen, da dies die Bestandsverwaltung verkompliziert. Die Rohstoffliste bei
openbewirkt, dass Beancount eine fehlgeleitete Buchung ablehnt, anstatt zwei Bestände stillschweigend zu vermischen. -
Lot-Verwaltung:
-
Verwenden Sie aussagekräftige Labels für Lots, insbesondere für spezifische Transaktionen wie Tax-Loss-Harvesting oder Mitarbeiteraktienzuteilungen.
Assets:Invest:STOCK 10 STOCK {100.00 USD, "tax-loss-harvest-2024"} -
Dokumentieren Sie Ihre Trades mit Kommentaren. Dies macht Ihr Ledger später leichter lesbar und verständlich.
Assets:Invest:STOCK -10 STOCK {100.00 USD} @ 110.00 USD ; Gain: 10%
- Fehlersuche: Wenn Sie auf Fehler oder unerwartetes Verhalten stoßen, bietet Beancount Werkzeuge zur Untersuchung des Zustands Ihres Bestands.
-
Bestandszustand untersuchen: Verwenden Sie
bea doctor context main.beancount 42, um die Transaktion in Zeile 42 zu untersuchen, einschließlich ihrer Buchungen und der betroffenen Kontosalden. Ersetzen Sie den Dateinamen und die Zeilennummer durch die Transaktion, die Sie untersuchen möchten.Ersetzen Sie
<LINENO>durch die Zeilennummer direkt nach einer Transaktion, um ihre Auswirkung zu sehen. -
Lot-Zuordnung überprüfen: Das Tool
bea checkvalidiert Ihre gesamte Datei. Es wird alle Buchungsfehler erkennen, wie mehrdeutige Lot-Übereinstimmungen imSTRICT-Modus.