Het voorraadbeheersysteem van Beancount is een krachtige functie voor het bijhouden van activa die in de loop van de tijd worden gekocht en verkocht, zoals aandelen, beleggingsfondsen of vreemde valuta. Het maakt nauwkeurige tracking van de kostprijs mogelijk, wat essentieel is voor het berekenen van vermogenswinsten en het begrijpen van portefeuilleprestaties. Deze tutorial behandelt de kernmechanieken van het beheren van voorraden in uw grootboek.
Kernbegrippen
In de kern draait voorraadbeheer om het bijhouden van posities. Een "positie" is simpelweg een hoeveelheid van een handelswaar die in een rekening wordt gehouden. Beancount onderscheidt twee fundamentele types posities.
Positietypen
-
Eenvoudige positie (zonder kostprijs): Dit is een standaard saldopostering. Het vertegenwoordigt een hoeveelheid van een handelswaar zonder enige bijbehorende aanschafkost. Het is geschikt voor contanten of eenvoudige saldobeweringen.
Assets:Bank:Checking 100.00 USD -
Positie met kostprijs: Dit type positie omvat niet alleen het aantal eenheden en de handelswaar, maar ook de kostprijs waartegen het is verworven. Dit is de basis van voorraadtracking. De kostprijs wordt gespecificeerd binnen accolades
{}.Assets:Invest:VTSAX 10 VTSAX {100.00 USD, "lot-1"}In dit voorbeeld hebben we 10 eenheden van
VTSAX. Elke eenheid werd verworven tegen een kostprijs van $100.00 USD. Deze specifieke batch aandelen wordt een "lot" genoemd.
Voorraadbewerkingen
Er zijn twee primaire bewerkingen die u kunt uitvoeren op een voorraad:
-
Vermeerderingen (toevoegen aan voorraad): Wanneer u een handelswaar koopt, vermeerdert u uw voorraad. U maakt een nieuw lot aan met een specifiek aantal eenheden en een kostprijs.
2024-01-15 * "Buy shares" Assets:Invest:STOCK 50 STOCK {25.00 USD, "lot-1"} Assets:Bank:Checking -1250.00 USDHier kopen we 50 eenheden van
STOCKtegen een eenheidskostprijs van $25.00 USD. Dit maakt een lot aan in deAssets:Invest:STOCK-rekening. -
Verminderingen (verwijderen uit voorraad): Wanneer u een handelswaar verkoopt, vermindert u uw voorraad. U moet specificeren uit welk lot u verkoopt. Dit doet u door overeenkomende informatie binnen de accolades te verstrekken.
2024-01-20 * "Sell shares" Assets:Invest:STOCK -25 STOCK {25.00 USD} Assets:Bank:Checking 625.00 USDIn deze transactie verkopen we 25 eenheden van
STOCKuit het lot dat gekocht is tegen $25.00 USD per eenheid.
Boekingmethoden
Wanneer u een voorraad vermindert, heeft Beancount een regel nodig om te bepalen uit welk specifiek lot moet worden weggenomen als meerdere loten aan de vermindering voldoen. Deze regel heet de "boekingmethode." U kunt een standaard instellen voor het hele bestand met een optie, of een rekening een eigen methode geven op de open-richtlijn.
Beancount 3.2.3 accepteert zeven methodenamen: STRICT (de standaard), STRICT_WITH_SIZE, NONE, FIFO, LIFO, HIFO en AVERAGE. Zes daarvan zijn geïmplementeerd; AVERAGE wordt geparsed maar geeft een fout zodra het een reductie moet verwerken, zoals de AVERAGE sectie hieronder laat zien.
1. STRICT (Standaard)
De STRICT methode is de standaard en de veiligste boekingsmethode. Het dwingt expliciete en eenduidige matching af.
2024-01-01 open Assets:Invest:STOCK "STRICT"- Vereist Exacte Lot-matching: De kostenspecificatie (
{...}) van de reductieboeking moet een enkel lot identificeren — op kostprijs, op datum van aanschaf, op label, of een combinatie daarvan. - Fouten bij Ambiguïteit: Als de specificatie meer dan één lot matcht, geeft Beancount een
AmbiguousMatchErrorfout in plaats van giswerk. - Uitzondering: Als een reductie exact het totaal aantal eenheden verwijdert dat de specificatie matcht, is een lege specificatie (
{}) toegestaan en wordt de reductie over die loten verdeeld.
Dit grootboek bevat twee loten en verkoopt er één door de kostprijs ervan te noemen, wat onambigu is:
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:GainsHet wordt geladen zonder fouten, boekt $300,00 winst aan Income:Gains, en laat een 10 STK {100.00 USD} in de rekening staan.
Vervang die laatste boeking door een lege specificatie en hetzelfde bestand faalt:
; 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 meldt Ambiguous matches for "-10 STK {}" en geeft de kandidaten weer. Het verkopen van de hele positie is echter toegestaan, omdat er dan niets meer ter keuze overblijft:
; 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:GainsDat boekt $800,00 winst — $3.000,00 opbrengst tegen $1.000,00 + $1.200,00 kostprijs — en laat de rekening leeg achter. Dit is een eigenschap van STRICT zelf, en geen reden om over te schakelen naar STRICT_WITH_SIZE.
2. FIFO (First-In, First-Out)
De FIFO methode boekt automatisch reducties tegen de oudste beschikbare loten eerst.
2024-01-01 open Assets:Invest:STOCK "FIFO"- Automatische Resolutie: Het lost ambiguïteit op door de oudste matching loten te selecteren.
- Chronologische Matching: Je gaat ervan uit dat je de activa verkoopt die je het langst hebt gehad. Verschillende belastingautoriteiten beschouwen dit als standaard als er geen lot is aangegeven.
3. LIFO (Last-In, First-Out)
De LIFO methode is het tegenovergestelde van FIFO. Het boekt reducties eerst tegen de nieuwste beschikbare loten.
2024-01-01 open Assets:Invest:STOCK "LIFO"- Omgekeerde chronologische volgorde: Het selecteert de laatst verworven overeenkomstige lots.
- Nieuwste, niet duurste: LIFO kiest alleen op aankoopdatum. Het verkoopt toevallig de aandelen met de hoogste kosten wanneer de prijzen stijgen, maar als je nieuwste lot je goedkoopste is — wat het onderstaande voorbeeld laat zien — zal LIFO de grootste opbrengst realiseren, niet de kleinste. De methode die altijd de duurste aandelen verkoopt is
HIFO, hierna beschreven.
4. HIFO (Highest-In, First-Out)
De HIFO-methode boekt verminderingen eerst weg tegen de duurste beschikbare lots, ongeacht hun datum.
2024-01-01 open Assets:Invest:STOCK "HIFO"- Kosten-gerangschikte matching: Het selecteert de overeenkomende lots met de hoogste kostprijs.
- Kleinste gerealiseerde winst: Bij een bepaalde verkoopprijs realiseert de verkoop van aandelen met de hoogste kosten de kleinste winst (of het grootste verlies). Of je het mag gebruiken is een jurisdictie-kwestie — in de Verenigde Staten bijvoorbeeld vereist het kiezen van een lot een specifieke identificatie op het moment van verkoop — dus behandel de methode als een boekhoudmechanisme en bevestig de fiscale keuze apart.
5. Vergelijking van FIFO, LIFO en HIFO op dezelfde lots
De drie methoden verschillen alleen wanneer het oudste, het nieuwste en het duurste lot drie verschillende lots zijn. Dit grootboek regelt precies dat — lot A is het oudste, lot C is het nieuwste, en het middelste lot B is het duurste — en verkoopt vervolgens 10 aandelen uit drie accounts die alleen verschillen in hun boekhoudmethode:
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:GainsHet laadt zonder fouten en boekt in totaal $1,400.00 winst, opgesplitst als volgt:
| Account | Methode | Lot geboekt | Kostprijs | Gerealiseerde winst | Nog resterende lots |
|---|---|---|---|---|---|
Assets:Broker:Fifo | FIFO | lot A, 2024-01-10 | $100.00 | $500.00 | 10 @ $120.00, 10 @ $90.00 |
Assets:Broker:Lifo | LIFO | lot C, 2024-03-10 | $90.00 | $600.00 | 10 @ $100.00, 10 @ $120.00 |
Assets:Broker:Hifo | HIFO | lot B, 2024-02-10 | $120.00 | $300.00 | 10 @ $100.00, 10 @ $90.00 |
De LIFO-rij is degene om naar te kijken: die realiseerde de grootste winst van de drie, omdat het nieuwste lot ook het goedkoopste was.
6. STRICT_WITH_SIZE
STRICT_WITH_SIZE is STRICT plus één extra beslisser: als meerdere lots overeenkomen, maar precies één ervan het exacte aantal eenheden bevat dat je verwijdert, wordt dat lot gekozen.
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:GainsDat boekt $210,00 winst tegen het lot van $120,00. Het identieke bestand met "STRICT" op de open-regel mislukt met Ambiguous matches for "-7 STK {}".
7. GEMIDDELDE (geaccepteerd, maar niet geïmplementeerd)
AVERAGE is een geldige naam — option "booking_method" "AVERAGE" en open … "AVERAGE" worden beide geparst — maar Beancount 3.2.3 heeft hier geen implementatie achter. Alles laadt tot de verkoop:
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:GainsOp het moment dat die afschrijving geboekt moet worden, stopt de loader met:
AVERAGE method is not supportedPlan geen grootboek daaromheen. Als je vandaag gedrag met gemiddelde kosten wilt, houd de positie dan in een NONE-account en bereken zelf het gemiddelde, of volg elk lot en accepteer winst per lot.
8. GEEN
De NONE-methode schakelt lotmatching volledig uit.
2024-01-01 open Assets:Invest:STOCK "NONE"- Geen lotmatching: Beancount probeert geen afschrijvingen te koppelen aan toevoegingen.
- Sta gemengde tekens toe: Hiermee kan een account zowel positieve als negatieve saldi van dezelfde grondstof tegelijk bevatten. Dit gedrag is vergelijkbaar met hoe het Ledger CLI-hulpmiddel grondstoffen behandelt.
Lotspecificatie
Een "lot" is een specifiek blok van een grondstof dat op een bepaald moment en tegen een bepaalde prijs is verworven. Wanneer je een positie creëert of vermindert, kun je de lotkenmerken in detail specificeren.
Volledige specificatie
Bij het aanvullen van een voorraad (aankopen) kun je tot drie attributen voor het lot opgeven, gescheiden door komma's binnen één paar accolades:
Assets:Invest:STOCK 10 STOCK {100.00 USD, 2024-01-15, "lot-identifier"}100.00 USD— de kostprijs, uitgedrukt per eenheid.2024-01-15— de datum van aanschaf. Beancount vult dit in op basis van de transactiedatum als je het weglaat, daarom tonen foutmeldingen hierboven een datum bij elk lot."lot-identifier"— een optionele stringlabel.
Hoewel alle drie optioneel zijn, is het standaardpraktijk om ten minste de kostprijs op te geven. De accolades moeten op één regel blijven, en opmerkingen binnen een grootboek beginnen met ;, nooit met #.
Matchingsmethoden
Bij het verminderen van een voorraad (verkopen) gebruik je dezelfde syntax om aan te geven van welk(e) lot(s) verkocht wordt.
-
Match op kosten: Dit is de meest voorkomende methode.
Assets:Invest:STOCK -5 STOCK {100.00 USD} -
Match op datum: Als de kosten identiek zijn, kun je dit verder onderscheiden op basis van de aanschafdatum.
Assets:Invest:STOCK -5 STOCK {2024-01-15} -
Match op label: Labels bieden een onfeilbare manier om een lot te identificeren.
Assets:Invest:STOCK -5 STOCK {"lot-identifier"} -
Laat het lot over aan de boekingsmethode: Een leeg stel accolades
{}benoemt geen lot, dus kiest de boekingsmethode van het account. OnderFIFO,LIFOofHIFOis dat het oudste, nieuwste of duurste passende lot; onder de standaardSTRICTis het eenAmbiguousMatchErrortenzij de afschrijving de gekoppelde loten precies leegt.Assets:Invest:STOCK -5 STOCK {}
Prijsverwerking
Het is cruciaal om het verschil te begrijpen tussen cost basis ({}) en price (@). Ze dienen verschillende doeleinden en zijn niet uitwisselbaar.
Prijs vs Kosten
{cost}: Definieert de aankoopprijs van een actief. Het maakt deel uit van de voorraadpartij zelf en wordt gebruikt voor het boeken van afnames en het berekenen van vermogenswinst.@ price: Een annotatie die een marktprijs registreert op het moment van een transactie. Het wordt gebruikt voor valutaconversies of om de marktwaarde op een specifieke datum te noteren.
Hier zijn de drie scenario's:
-
Prijsannotatie (Conversie): Gebruik
@om van de ene valuta naar de andere te converteren.Assets:Forex 1000 USD @ 0.85 EUR -
Cost Basis (Aankoop): Gebruik
{}bij het kopen van een actief om de kosten vast te stellen.Assets:Invest 10 STOCK {100.00 USD} -
Beide (Verkoop met Prijsregistratie): Bij het verkopen van een actief gebruikt u
{}om de verkochte partij te identificeren en@om de verkoopprijs vast te leggen. Dit maakt geautomatiseerde vermogenswinstberekening mogelijk.Assets:Invest -10 STOCK {100.00 USD} @ 105.00 USDDeze boeking verkoopt 10
STOCKvan de partij die elk $100,00 kostte, tegen een verkoopprijs van elk $105,00.
Regels voor Prijsgebruik
- Prijsannotaties (
@) beïnvloeden niet welke partij wordt geboekt. Partijmatching wordt uitsluitend geregeld door de cost basis ({}) en de boekingswijze van de rekening. - Het symbool
@wordt alleen gebruikt voor:
- Valutaconversies.
- Het vastleggen van de marktwaarde van een actief op het moment van een transactie.
- Het aangeven van de verkoopprijs voor vermogenswinstberekeningen.
Configuratie
U kunt boekingswijzen globaal of per rekening configureren.
Globale Boekingswijze
U kunt een standaard boekingswijze voor uw gehele Beancount-bestand instellen via de option-richtlijn.
option "booking_method" "STRICT"De geaccepteerde waarden zijn "STRICT" (de standaard wanneer u niets instelt), "STRICT_WITH_SIZE", "NONE", "FIFO", "LIFO", "HIFO" en "AVERAGE". Elke andere string wordt bij het laden afgewezen met Error for option 'booking_method'. "AVERAGE" wordt hier en op open geaccepteerd, maar een afname boeken onder deze mislukt, zoals de AVERAGE sectie hierboven laat zien.
Per-Rekening Override
Het is vaak nuttig om verschillende methoden voor verschillende rekeningen te hebben. Bijvoorbeeld, u wilt mogelijk FIFO voor een pensioenrekening, maar STRICT voor een belastbare effectenrekening om ervoor te zorgen dat u specifieke fiscale partijen verkoopt. U kunt de boekingswijze instellen bij het openen van de rekening.
2024-01-01 open Assets:Retirement:401K "FIFO"
2024-01-01 open Assets:Taxable:Stock "STRICT"Best Practices
-
Voorraadorganisatie: Om uw grootboek schoon en eenvoudig te houden, wordt sterk aanbevolen om aparte rekeningen te gebruiken voor elke unieke handelswaar die u bezit, en om elke rekening te beperken tot die handelswaar op haar
open-richtlijn.; GOOD: separate accounts by commodity, each constrained to one 2024-01-01 open Assets:Invest:VTSAX VTSAX 2024-01-01 open Assets:Invest:VFIAX VFIAXVermijd het mengen van verschillende aandelen of fondsen in dezelfde rekening, omdat dit het voorraadbeheer bemoeilijkt. De productlijst op
openzorgt ervoor dat Beancount een verkeerde boeking afwijst in plaats van twee voorraden stilzwijgend te mengen. -
Lotbeheer:
-
Gebruik betekenisvolle labels voor lots, vooral voor specifieke transacties zoals tax-loss harvesting of aandelen toegekend aan werknemers.
Assets:Invest:STOCK 10 STOCK {100.00 USD, "tax-loss-harvest-2024"} -
Documenteer je transacties met opmerkingen. Dit maakt je grootboek later makkelijker te lezen en te begrijpen.
Assets:Invest:STOCK -10 STOCK {100.00 USD} @ 110.00 USD ; Gain: 10%
- Debugging: Als je fouten of onverwacht gedrag tegenkomt, biedt Beancount tools om de staat van je voorraad te inspecteren.
-
Voorraadstatus onderzoeken: Gebruik
bea doctor context main.beancount 42om de transactie op regel 42 te bekijken, inclusief de bijbehorende boekingen en de beïnvloedde rekeningsaldi. Vervang de bestandsnaam en het regelnummer door de transactie die je wil inspecteren.Vervang
<LINENO>door het regelnummmer direct na een transactie om het effect ervan te zien. -
Lotmatching verifiëren: De
bea check-tool valideert je gehele bestand. Het zal elke boekingsfout detecteren, zoals ambiguë lotmatches in deSTRICT-modus.