Il sistema di inventario di Beancount è una funzionalità potente per monitorare le attività che vengono acquistate e vendute nel tempo, come azioni, fondi comuni o valute estere. Consente un monitoraggio preciso della base di costo, essenziale per calcolare le plusvalenze e comprendere la performance del portafoglio. Questo tutorial copre i meccanismi fondamentali della gestione degli inventari nel tuo ledger.
Concetti Fondamentali
Nel suo nucleo, la gestione dell'inventario ruota attorno al monitoraggio delle posizioni. Una "posizione" è semplicemente una quantità di una commodity detenuta in un conto. Beancount distingue tra due tipi fondamentali di posizioni.
Tipi di Posizione
-
Posizione semplice (senza costo): Si tratta di una registrazione di saldo standard. Rappresenta una quantità di una commodity senza alcun costo di acquisizione associato. È adatta per la liquidità o per semplici asserzioni di saldo.
Assets:Bank:Checking 100.00 USD -
Posizione con base di costo: Questo tipo di posizione include non solo il numero di unità e la commodity, ma anche il costo al quale è stata acquisita. Questa è la base del monitoraggio dell'inventario. Il costo è specificato all'interno delle parentesi graffe
{}.Assets:Invest:VTSAX 10 VTSAX {100.00 USD, "lot-1"}In questo esempio, deteniamo 10 unità di
VTSAX. Ogni unità è stata acquisita a un costo di 100,00 USD. Questo specifico blocco di quote è identificato come un "lotto".
Operazioni sull'Inventario
Ci sono due operazioni principali che puoi eseguire su un inventario:
-
Aumenti (aggiunta all'inventario): Quando acquisti una commodity, aumenti il tuo inventario. Crei un nuovo lotto con un numero specifico di unità e una base di costo.
2024-01-15 * "Buy shares" Assets:Invest:STOCK 50 STOCK {25.00 USD, "lot-1"} Assets:Bank:Checking -1250.00 USDQui acquistiamo 50 unità di
STOCKa un costo per unità di 25,00 USD. Questo crea un lotto nel contoAssets:Invest:STOCK. -
Riduzioni (rimozione dall'inventario): Quando vendi una commodity, riduci il tuo inventario. Devi specificare da quale lotto stai vendendo. Questo si fa fornendo le informazioni corrispondenti all'interno delle parentesi graffe.
2024-01-20 * "Sell shares" Assets:Invest:STOCK -25 STOCK {25.00 USD} Assets:Bank:Checking 625.00 USDIn questa transazione, stiamo vendendo 25 unità di
STOCKdal lotto che è stato acquistato a 25,00 USD per unità.
Metodi di Registrazione
Quando riduci un inventario, Beancount necessita di una regola per decidere da quale lotto specifico attingere se diversi lotti corrispondono alla riduzione. Questa regola è chiamata "metodo di prenotazione". Puoi impostare un valore predefinito per l'intero file con un'opzione, oppure assegnare a un conto il proprio metodo nella direttiva open.
Beancount 3.2.3 accetta sette nomi di metodo: STRICT (il valore predefinito), STRICT_WITH_SIZE, NONE, FIFO, LIFO, HIFO e AVERAGE. Sei di essi sono implementati; AVERAGE viene analizzato ma genera un errore nel momento in cui deve prenotare una riduzione, come mostra la sezione AVERAGE di seguito.
1. STRICT (Predefinito)
Il metodo STRICT è il valore predefinito e il metodo di prenotazione più sicuro. Impone una corrispondenza esplicita e non ambigua.
2024-01-01 open Assets:Invest:STOCK "STRICT"- Richiede una corrispondenza esatta del lotto: Lo specificatore di costo della registrazione di riduzione (
{...}) deve identificare un singolo lotto — per costo, per data di acquisizione, per etichetta o per qualsiasi combinazione di essi. - Errore in caso di corrispondenze ambigue: Se lo specificatore corrisponde a più di un lotto, Beancount genera un
AmbiguousMatchErrorinvece di indovinare. - Eccezione: Se una riduzione rimuove esattamente il numero totale di unità a cui corrisponde lo specificatore, è consentito uno specificatore vuoto (
{}) e la riduzione viene suddivisa tra quei lotti.
Questo ledger contiene due lotti e ne vende uno indicandone il costo, che è inequivocabile:
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:GainsSi carica senza errori, prenota 300,00 $ di plusvalenza su Income:Gains e lascia 10 STK {100.00 USD} nel conto.
Sostituisci quest'ultima registrazione con uno specificatore vuoto e lo stesso file fallisce:
; 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 segnala Ambiguous matches for "-10 STK {}" ed elenca i candidati. Vendere l'intera posizione va bene, però, perché non resta nulla tra cui scegliere:
; 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:GainsQuesto prenota 800,00 $ di plusvalenza — 3.000,00 $ di proventi contro 1.000,00 $ + 1.200,00 $ di base — e lascia il conto vuoto. Questa è una proprietà di STRICT stesso, non qualcosa per cui devi passare a STRICT_WITH_SIZE.
2. FIFO (First-In, First-Out)
Il metodo FIFO prenota automaticamente le riduzioni sui lotti disponibili più vecchi per primi.
2024-01-01 open Assets:Invest:STOCK "FIFO"- Risoluzione automatica: Risolve l'ambiguità selezionando i lotti corrispondenti più vecchi.
- Corrispondenza cronologica: Si presume che tu stia vendendo le attività che hai detenuto più a lungo. Diverse autorità fiscali lo considerano il valore predefinito quando non hai identificato un lotto.
3. LIFO (Last-In, First-Out)
Il metodo LIFO è l'opposto di FIFO. Prenota le riduzioni sui lotti disponibili più recenti per primi.
2024-01-01 open Assets:Invest:STOCK "LIFO"- Ordine cronologico inverso: Seleziona i lotti corrispondenti acquisiti più di recente.
- Più recente, non più costoso: LIFO seleziona solo in base alla data di acquisizione. Capita di vendere le quote a costo più alto quando i prezzi sono aumentati, ma se il tuo lotto più recente è anche il più economico — che è ciò che l'esempio seguente è costruito per mostrare — LIFO realizzerà la plusvalenza maggiore, non la minore. Il metodo che vende sempre le quote più costose è
HIFO, descritto di seguito.
4. HIFO (Highest-In, First-Out)
Il metodo HIFO prenota le riduzioni sui lotti disponibili più costosi per primi, indipendentemente dalla loro data.
2024-01-01 open Assets:Invest:STOCK "HIFO"- Corrispondenza ordinata per costo: Seleziona i lotti corrispondenti con la base di costo più alta.
- Plusvalenza realizzata più piccola: Per un dato prezzo di vendita, vendere le quote a costo più alto realizza la plusvalenza più piccola (o la perdita più grande). Se puoi usarlo è una questione di giurisdizione — negli Stati Uniti, ad esempio, scegliere un lotto richiede comunque un'identificazione specifica al momento della vendita — quindi considera il metodo come un meccanismo contabile e conferma separatamente l'elezione fiscale.
5. Confronto tra FIFO, LIFO e HIFO sugli stessi lotti
I tre metodi differiscono solo quando il lotto più vecchio, il più recente e il più costoso sono tre lotti diversi. Questo ledger organizza esattamente questa situazione — il lotto A è il più vecchio, il lotto C è il più recente e il lotto intermedio B è il più costoso — e poi vende 10 quote da tre conti che differiscono solo per il loro metodo di prenotazione:
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:GainsSi carica senza errori e prenota 1.400,00 $ di plusvalenza in totale, suddivisa così:
| Conto | Metodo | Lotto prenotato | Base di costo | Plusvalenza realizzata | Lotti rimanenti |
|---|---|---|---|---|---|
Assets:Broker:Fifo | FIFO | lotto A, 2024-01-10 | 100,00 $ | 500,00 $ | 10 @ 120,00 $, 10 @ 90,00 $ |
Assets:Broker:Lifo | LIFO | lotto C, 2024-03-10 | 90,00 $ | 600,00 $ | 10 @ 100,00 $, 10 @ 120,00 $ |
Assets:Broker:Hifo | HIFO | lotto B, 2024-02-10 | 120,00 $ | 300,00 $ | 10 @ 100,00 $, 10 @ 90,00 $ |
La riga LIFO è quella su cui vale la pena soffermarsi: ha realizzato la plusvalenza più grande delle tre, perché il lotto più recente era anche il più economico.
6. STRICT_WITH_SIZE
STRICT_WITH_SIZE è STRICT più un ulteriore criterio di risoluzione: quando diversi lotti corrispondono ma esattamente uno di essi contiene precisamente il numero di unità che stai rimuovendo, viene scelto quel lotto.
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:GainsQuesto prenota 210,00 $ di plusvalenza sul lotto da 120,00 $. Il file identico con "STRICT" sulla riga open fallisce con Ambiguous matches for "-7 STK {}".
7. AVERAGE (accettato, ma non implementato)
AVERAGE è un nome valido — sia option "booking_method" "AVERAGE" che open … "AVERAGE" vengono analizzati — ma Beancount 3.2.3 non ha alcuna implementazione dietro di esso. Tutto qui si carica fino alla vendita:
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:GainsNel momento in cui quella riduzione deve essere prenotata, il caricatore si ferma con:
AVERAGE method is not supportedNon pianificare un ledger attorno ad esso. Se desideri un comportamento a costo medio oggi, mantieni la posizione in un conto NONE e calcola tu stesso la media, oppure monitora ogni lotto e accetta le plusvalenze a livello di lotto.
8. NONE
Il metodo NONE disabilita completamente la corrispondenza dei lotti.
2024-01-01 open Assets:Invest:STOCK "NONE"- Nessuna corrispondenza dei lotti: Beancount non tenta di far corrispondere le riduzioni agli aumenti.
- Consente segni misti: Questo permette a un conto di detenere simultaneamente saldi sia positivi che negativi della stessa commodity. Questo comportamento è simile a come lo strumento CLI Ledger gestisce le commodity.
Specifica del lotto
Un "lotto" è un blocco specifico di una commodity acquisito in un particolare momento e a un particolare prezzo. Quando crei o riduci una posizione, puoi specificare i suoi attributi di lotto in dettaglio.
Specifica completa
Quando aumenti un inventario (acquisto), puoi specificare fino a tre attributi per il lotto, separati da virgole all'interno di una singola coppia di parentesi graffe:
Assets:Invest:STOCK 10 STOCK {100.00 USD, 2024-01-15, "lot-identifier"}100.00 USD— la base di costo, espressa per unità.2024-01-15— la data di acquisizione. Beancount la inserisce dalla data della transazione quando la ometti, motivo per cui i messaggi di errore sopra mostrano una data su ogni lotto."lot-identifier"— un'etichetta stringa opzionale.
Sebbene tutti e tre siano opzionali, fornire almeno la base di costo è una pratica standard. Le parentesi graffe devono rimanere su una riga e i commenti all'interno di un ledger iniziano con ;, mai con #.
Metodi di abbinamento
Quando riduci un inventario (vendita), usi la stessa sintassi per specificare da quale lotto (o lotti) vendere.
-
Corrispondenza per costo: Questo è il metodo più comune.
Assets:Invest:STOCK -5 STOCK {100.00 USD} -
Corrispondenza per data: Se i costi sono identici, puoi disambiguare usando la data di acquisizione.
Assets:Invest:STOCK -5 STOCK {2024-01-15} -
Corrispondenza per etichetta: Le etichette forniscono un modo infallibile per identificare un lotto.
Assets:Invest:STOCK -5 STOCK {"lot-identifier"} -
Lasciare il lotto al metodo di prenotazione: Un insieme vuoto di parentesi graffe
{}non nomina alcun lotto, quindi è il metodo di prenotazione del conto a scegliere. SottoFIFO,LIFOoHIFOè il lotto corrispondente più vecchio, più recente o più costoso; sotto il predefinitoSTRICTè unAmbiguousMatchErrora meno che la riduzione non esaurisca esattamente i lotti corrispondenti.Assets:Invest:STOCK -5 STOCK {}
Gestione dei prezzi
È cruciale comprendere la differenza tra base di costo ({}) e prezzo (@). Servono a scopi diversi e non sono intercambiabili.
Prezzo vs Costo
{cost}: Definisce il costo di acquisizione di un'attività. Fa parte del lotto di inventario stesso ed è utilizzato per prenotare le riduzioni e calcolare le plusvalenze.@ price: Un'annotazione che registra un prezzo di mercato al momento di una transazione. È utilizzato per conversioni valutarie o per annotare il valore di mercato in una data particolare.
Ecco i tre scenari:
-
Annotazione del prezzo (conversione): Usa
@per convertire da una valuta a un'altra.Assets:Forex 1000 USD @ 0.85 EUR -
Base di costo (acquisizione): Usa
{}quando acquisti un'attività per stabilirne il costo.Assets:Invest 10 STOCK {100.00 USD} -
Entrambi (vendita con registrazione del prezzo): Quando vendi un'attività, usa
{}per identificare il lotto in vendita e@per registrare il prezzo di vendita. Questo consente il calcolo automatizzato delle plusvalenze.Assets:Invest -10 STOCK {100.00 USD} @ 105.00 USDQuesta registrazione vende 10
STOCKdal lotto che è costato 100,00 $ ciascuno, a un prezzo di vendita di 105,00 $ ciascuno.
Una direttiva price autonoma fornisce dati di riferimento per la valutazione di mercato. I Prezzi in tempo reale possono mantenere queste direttive per le attività supportate nei ledger ospitati. Un aggiornamento lascia invariati i tuoi lotti, il metodo di prenotazione, i costi di acquisizione e i proventi di vendita registrati.
Regole per l'Uso del Prezzo
- Le annotazioni di prezzo (
@) non influenzano quale lotto viene prenotato. La corrispondenza dei lotti è gestita esclusivamente dalla base di costo ({}) e dal metodo di prenotazione del conto. - Il simbolo
@è utilizzato solo per:
- Conversioni valutarie.
- Registrare il valore di mercato di un'attività al momento di una transazione.
- Fornire il prezzo di vendita per i calcoli delle plusvalenze.
Configurazione
Puoi configurare i metodi di prenotazione a livello globale o per singolo conto.
Metodo di Registrazione Globale
Puoi impostare un metodo di prenotazione predefinito per l'intero file Beancount usando la direttiva option.
option "booking_method" "STRICT"I valori accettati sono "STRICT" (il valore predefinito quando non imposti nulla), "STRICT_WITH_SIZE", "NONE", "FIFO", "LIFO", "HIFO" e "AVERAGE". Qualsiasi altra stringa viene rifiutata al momento del caricamento con Error for option 'booking_method'. "AVERAGE" è accettato qui e su open, ma prenotare una riduzione sotto di esso fallisce, come mostra la sezione AVERAGE sopra.
Override per Account
Spesso è utile avere metodi diversi per conti diversi. Ad esempio, potresti voler usare FIFO per un conto pensionistico ma STRICT per un conto di intermediazione imponibile per assicurarti di vendere lotti fiscali specifici. Puoi impostare il metodo di prenotazione quando apri il conto.
2024-01-01 open Assets:Retirement:401K "FIFO"
2024-01-01 open Assets:Taxable:Stock "STRICT"Migliori Pratiche
-
Organizzazione dell'inventario: Per mantenere il tuo ledger pulito e semplice, è altamente raccomandato usare conti separati per ogni commodity unica che detieni e vincolare ciascuno a quella commodity nella sua direttiva
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 VFIAXEvita di mescolare azioni o fondi diversi nello stesso conto, poiché complica la gestione dell'inventario. L'elenco delle commodity su
openfa sì che Beancount rifiuti una registrazione estranea invece di mescolare silenziosamente due inventari. -
Gestione dei lotti:
-
Usa etichette significative per i lotti, specialmente per transazioni specifiche come la compensazione delle minusvalenze o le assegnazioni di azioni ai dipendenti.
Assets:Invest:STOCK 10 STOCK {100.00 USD, "tax-loss-harvest-2024"} -
Documenta le tue operazioni con commenti. Questo rende il tuo ledger più facile da leggere e comprendere in seguito.
Assets:Invest:STOCK -10 STOCK {100.00 USD} @ 110.00 USD ; Gain: 10%
- Debug: Se incontri errori o comportamenti imprevisti, Beancount fornisce strumenti per ispezionare lo stato del tuo inventario.
-
Esaminare lo stato dell'inventario: Usa
bea doctor context main.beancount 42per ispezionare la transazione alla riga 42, incluse le sue registrazioni e i saldi dei conti interessati. Sostituisci il nome del file e il numero di riga con la transazione che vuoi ispezionare.Sostituisci
<LINENO>con il numero di riga subito dopo una transazione per vederne l'effetto. -
Verificare la corrispondenza dei lotti: Lo strumento
bea checkconvalida l'intero file. Catturerà eventuali errori di prenotazione, come corrispondenze ambigue di lotti in modalitàSTRICT.