Системата за инвентар на Beancount е мощна функция за проследяване на активи, които се купуват и продават във времето, като акции, взаимни фондове или чуждестранни валути. Тя позволява прецизно проследяване на цената на придобиване, което е от съществено значение за изчисляване на капиталови печалби и разбиране на представянето на портфейла. Този урок обхваща управлението на инвентара във вашата счетоводна книга.
Основни концепции
В основата си управлението на инвентара се върти около проследяването на позиции. „Позиция“ е просто количество от дадена стока, държано в дадена сметка. Beancount прави разлика между два основни типа позиции.
Видове позиции
-
Проста позиция (без цена на придобиване): Това е стандартен балансов запис. Той представлява количество от стока без свързана цена на придобиване. Подходяща е за парични средства или прости балансови проверки.
Assets:Bank:Checking 100.00 USD -
Позиция с цена на придобиване: Този тип позиция включва не само броя на единиците и стоката, но и цената, на която е била придобита. Това е основата на проследяването на инвентара. Цената е посочена в гъвкави скоби
{}.Assets:Invest:VTSAX 10 VTSAX {100.00 USD, "lot-1"}В този пример държим 10 единици от
VTSAX. Всяка единица е била придобита на цена от $100.00 USD. Тази конкретна партида акции е идентифицирана като „партида“ (lot).
Операции с инвентара
Има два основни вида операции, които можете да извършите върху инвентара:
-
Увеличения (добавяне към инвентара): Когато купувате стока, вие увеличивате инвентара си. Вие създавате нова партида с конкретен брой единици и цена на придобиване.
2024-01-15 * "Buy shares" Assets:Invest:STOCK 50 STOCK {25.00 USD, "lot-1"} Assets:Bank:Checking -1250.00 USDТук купуваме 50 единици от
STOCKна цена от $25.00 USD за единица. Това създава партида в сметкатаAssets:Invest:STOCK. -
Намаления (премахване от инвентара): Когато продавате стока, вие намалявате инвентара си. Трябва да посочите от коя партида продавате. Това се прави, като предоставите съответстваща информация в гъвкавите скоби.
2024-01-20 * "Sell shares" Assets:Invest:STOCK -25 STOCK {25.00 USD} Assets:Bank:Checking 625.00 USDВ тази транзакция продаваме 25 единици от
STOCKот партидата, която е била закупена на цена от $25.00 USD за единица.
Методи за осчетоводяване (Booking Methods)
Когато намалявате инвентар, Beancount се нуждае от правило, за да реши от коя конкретна партида да тегли, ако няколко партиди съответстват на намалението. Това правило се нарича „метод на осчетоводяване“. Можете да зададете метод по подразбиране за целия файл с опция, или да дадете на конкретна сметка свой собствен метод в директивата open.
Beancount 3.2.3 приема седем имена на методи: STRICT (по подразбиране), STRICT_WITH_SIZE, NONE, FIFO, LIFO, HIFO и AVERAGE. Шест от тяx са имплементирани; AVERAGE се парсира, но предизвиква грешка в момента, в който трябва да осчетоводи намаление, както е показано в раздела AVERAGE по-долу.
1. STRICT (По подразбиране)
Методът STRICT е по подразбиране и най-сигурният метод на осчетоводяване. Той налага явно и недвузсмислено съвпаденение.
2024-01-01 open Assets:Invest:STOCK "STRICT"- Изисква точно съвпадение на партидата: Спецификаторът на разходите (
{...}) в пост-записа за намаление трябва да идентифицира една единствена партида – по цена, по дата на придобиване, по етикет или по комбинация от тях. - Грешка при двузсмислени съвпаденения: Ако спецификаторът съвпаднае с повече от една партида, Beancount издава
AmbiguousMatchError, вместо да гада. - Изклчение: Ако намалението премахва точно общия брой единици, с които съвпадна спецификаторът, е позволено празна спецификатор (
{}) и намалението се разделя межди тези партиди.
Таззи сметководна книга съдържа две партиди и продава една от тях, като посочва нейната цена, което е недвузсмислено:
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Той се зарежда без грешки, осчетоводява $300.00 печалба в Income:Gains и оставя 10 STK {100.00 USD} в сметката.
Заменете последниа пост-запис с празна спецификатор и същия файл се проваля:
; 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 докладва Ambiguous matches for "-10 STK {}" и излиства кандидатите. Продажбата на цялата позиция обаче е позволена, защото не оства нищо за избиране:
; 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Това осчетоводява $800.00 печалба – $3,000.00 приходи срещу $1,000.00 + $1,200.00 база – и оставя сметката празна. Това е свойство на самия STRICT, а не нещо, за което трябва да превключите на STRICT_WITH_SIZE.
2. FIFO (Първи-в-ърви-навън)
Методът FIFO автоматично осчетоводява намалението срещу най-старите налични партиди.
2024-01-01 open Assets:Invest:STOCK "FIFO"- Автоматично решаване: Той разрешава двузсмислеността, като избира най-старите съвпадащи партиди.
- Хронологично съвпадане: Пре дполагате, че продавате активите, които сте държали най-дълго. Много данъчни органи считат това за подразбиране, когато не сте идентифицирали партида.
3. LIFO (Последен-в-последен-навън)
LIFO методът е обратен на FIFO. Той осчетоводява намалението срещу най-новите налични партиди.
2024-01-01 open Assets:Invest:STOCK "LIFO"- Обратен хронологичен ред: Той избира най-скоро придобитите съвпадащи партиди.
- Най-нова, не най-скъпа: LIFO избира само по дата на придобиване. Случва се да продаде най-скъпите акции, когато ценете са се поенаваали, но ако най-новата ви партида е най-евтината – което примерът по-долу има за цел да покаже – LIFO ще реализира най-голямта печалба, а не най-малката. Методът, които винаги продава най-скъпите акции, е
HIFO, описан по-долу.
4. HIFO (Най-скъп-в-най-скъп-навън)
Методът HIFO осчетоводява намаленията срещу най-скъпите налични партиди, независимо от тяхната дата.
2024-01-01 open Assets:Invest:STOCK "HIFO"- Класиране по цена: Той избира съвпадащите партиди с най-висока цена на придобиване.
- Най-малка реализирана печалба: За дадена продажна цена, продажбата на най-скъпите акции реализира най-малката печалба (или най-голямата загуба). Дали можете да го използвате е въпрос на юрисдикцията – в Съединените щати, например, изборът на партида изисква конкретна идентификация по време на продажбата – така че третирайте метода като счетоводен механизъм и потвърдете данъчния избор отделно.
5. Сравнение на FIFO, LIFO и HIFO върху едни и същи партиди
Тези три метода се различават само когато най-старата, най-новата и най-скъпата партида са три различни партиди. Тази счетоводна книга подрежда точно това – партида А е най-старата, партида С е най-новата, а средната партида Б е най-скъпата – и след това продава 10 акции от три сметки, които се различават само по своя метод на осчетоводяване:
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Той се зарежда с нула грешки и осчетоводява общо $1,400.00 печалба, разделена така:
| Сметка | Метод | Осчетоводена партида | Цена на придобиване | Реализирана печалба | Оставащи партиди |
|---|---|---|---|---|---|
Assets:Broker:Fifo | FIFO | партида А, 2024-01-10 | $100.00 | $500.00 | 10 @ $120.00, 10 @ $90.00 |
Assets:Broker:Lifo | LIFO | партида С, 2024-03-10 | $90.00 | $600.00 | 10 @ $100.00, 10 @ $120.00 |
Assets:Broker:Hifo | HIFO | партида Б, 2024-02-10 | $120.00 | $300.00 | 10 @ $100.00, 10 @ $90.00 |
Редът LIFO е този, който си струва да се разгледа: той реализира най-голямата печалба от трите, защото най-новата партида беше и най-евтината.
6. STRICT_WITH_SIZE
STRICT_WITH_SIZE е STRICT плюс едно допълнително правило за разрешаване на равенство: когато няколко партиди съвпадат, но точно една от тях съдържа точно броя единици, които премахвате, тази партида се избира.
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Това осчетоводява $210.00 печалба срещу партидата от $120.00. Идентичният файл с "STRICT" на реда open се проваля с Ambiguous matches for "-7 STK {}".
7. AVERAGE (приет, но не имплементиран)
AVERAGE е валидно име – option "booking_method" "AVERAGE" и open … "AVERAGE" се парсират – но Beancount 3.2.3 няма имплементация зад него. Всичко тук се зарежда до продажбата:
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В момента, в който това намаление трябва да бъде осчетоводено, зареждащият механизъм спира с:
AVERAGE method is not supportedНе планирайте счетоводна книга около него. Ако искате средно-претеглено поведение днес, дръжте позицията в сметка NONE и изчислете средната стойност сами, или проследявайте всяка партида и приемайте печалби на ниво партида.
8. NONE
Методът NONE напълно деактивира съвпадението на партиди.
2024-01-01 open Assets:Invest:STOCK "NONE"- Без съвпадение на партиди: Beancount не се опитва да съпостави намаленията с увеличенията.
- Позволява смесени знаци: Това позволява на сметката да държи едновременно положителни и отрицателни баланси от една и съща стока. Това поведение е подобно на начина, по който инструментът Ledger CLI обработва стоките.
Спецификация на партидата
„Партида“ е конкретен блок от стока, придобит в определено време и на определена цена. Когато създавате или намалявате позиция, можете да посочите атрибутите на нейната партида в детайли.
Пълна спецификация
Когато увеличавате инвентара (купувате), можете да посочите до три атрибута за партидата, разделени със запетая в една двойка скоби:
Assets:Invest:STOCK 10 STOCK {100.00 USD, 2024-01-15, "lot-identifier"}100.00 USD— цената на придобиване, изразена за единица.2024-01-15— датата на придобиване. Beancount я попълва от датата на транзакцията, когато я пропуснете, поради което съобщенията за грешки по-горе показват дата на всяка партида."lot-identifier"— незадължителен низов етикет.
Въпреки че и трите са незадължители, предоставянето поне на цената на придобиване е стандартна практика. Скобите трябва да останат на един ред, а коментарите в счетоводната книга започват с ;, никога с #.
Методи за съвпадение
Когато намалявате инвентара (продавате), използвате същия синтаксис, за да посочите от коя(и) партида(и) продавате.
-
Съвпадение по цена: Това е най-често срещаният метод.
Assets:Invest:STOCK -5 STOCK {100.00 USD} -
Съвпадение по дата: Ако цените са идентични, можете да разрешите нееднозначността, като използвате датата на придобиване.
Assets:Invest:STOCK -5 STOCK {2024-01-15} -
Съвпадение по етикет: Етикетите предоставят безпогрешен начин за идентифициране на партида.
Assets:Invest:STOCK -5 STOCK {"lot-identifier"} -
Оставете партидата на метода на осчетоводяване: Празен набор от скоби
{}не посочва партида, така че методът на осчетоводяване на сметката избира. ПриFIFO,LIFOилиHIFOтова е най-старата, най-новата или най-скъпата съвпадаща партида; при подразбиращия сеSTRICTтова еAmbiguousMatchError, освен ако намалението не изпразва точно съвпадащите партиди.Assets:Invest:STOCK -5 STOCK {}
Обработка на цени
От решаващо значение е да разберете разликата между цена на придобиване ({}) и цена (@). Те служат за различни цели и не са взаимозаменяеми.
Цена срещу себестойност
{cost}: Определя цената на придобиване на даден актив. Тя е част от самата инвентарна партида и се използва за осчетоводяване на намаления и изчисляване на капиталови печалби.@ price: Анотация, която записва пазарна цена по време на транзакция. Използва се за валутни конвертирания или за отбелязване на пазарната стойност на определена дата.
Ето трите сценария:
-
Анотация за цена (конвертиране): Използвайте
@за конвертиране от една валута в друга.Assets:Forex 1000 USD @ 0.85 EUR -
Цена на придобиване (придобиване): Използвайте
{}при закупуване на актив, за да установите неговата себестойност.Assets:Invest 10 STOCK {100.00 USD} -
И две те (продажба с запис на цената): При продажба на актив, използвайте
{}, за да идентифицирате партидата, която се продава, и@, за да запишете продажната цена. Това позволява автоматично изчисляване на капиталови печалби.Assets:Invest -10 STOCK {100.00 USD} @ 105.00 USDТози запис продава 10
STOCKот партидата, която е струвала $100.00 за брой, на продажна цена от $105.00 за брой.
Правила за използване на цената
- Анотациите за цена (
@) не влияят на това коя партида се осчетоводява. Съвпадението на партиди се извършва изключително от цената на придобиване ({}) и метода на осчетоводяване на сметката. - Символът
@се използва само за:
- Валутни конвертирания.
- Записване на пазарната стоойност на актив към момента на транзакцията.
- Предоставяне на продажната цена за изчисляване на капиталови печалби.
Конфигурация
Можете да конфигурирате методите на осчетоводяване глобално или на ниво отделна сметка.
Глобален метод на осчетоводяване
Можете да зададете метод на осчетоводяване по подразбиране за целия си файл на Beancount, като използвате директивата option.
option "booking_method" "STRICT"Приетите стойности са "STRICT" (по подразбиране, когато не зададете нищо), "STRICT_WITH_SIZE", "NONE", "FIFO", "LIFO", "HIFO" и "AVERAGE". Всяка друга стойност се отхвърля при зареждане с Error for option 'booking_method'. "AVERAGE" се приема тук и при open, но осчетоводяването на намаление под него се проваля, както е показано в раздела AVERAGE по-горе.
Замяна на ниво сметка
Често е полезно да имате различни методи за различни сметки. Например, може да искате FIFO за пенсионна сметка, но STRICT за облагаема брокерска сметка, за да сте сигурни, че продавате конкретни данъчни партиди. Можете да зададете метода на осчетоводяване, когато отваряте сметката.
2024-01-01 open Assets:Retirement:401K "FIFO"
2024-01-01 open Assets:Taxable:Stock "STRICT"Най-добри практики
-
Организация на инвентара: За да поддържате счетоводната си книга чиста и проста, силно се препоръчва да използвате отделни сметки за всяка уникална стока, която притежавате, и да ограничите всяка от тях до тази стока в нейната директива
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Избягвайте смесването на различни акции или фондове в една и съща сметка, тъй като това усложнява управлението на инвентара. Списъкът със стоки при
openкара Beancount да отхвърли случайно публикуване, вместо мълчаливо да смеси два инвентара. -
Управление на партиди:
-
Използвайте смислени етикети за партидите, особено за конкретни транзакции като събиране на данъчни загуби или служителски акционерни грантове.
Assets:Invest:STOCK 10 STOCK {100.00 USD, "tax-loss-harvest-2024"} -
Документирайте сделките си с коментари. Това прави счетоводната ви книга по-лесна за четене и разбиране по-късно.
Assets:Invest:STOCK -10 STOCK {100.00 USD} @ 110.00 USD ; Gain: 10%
- Отстраняване на грешки: Ако срещнете грешки или неочаквано поведение, Beancount предоставя инструменти за проверка на състоянието на вашия инвентар.
-
Проверка на състоянието на инвентара: Използвайте
bea doctor context main.beancount 42, за да проверите транзакцията на ред 42, включително нейните публикации и засегнатите салда по сметки. Заменете името на файла и номера на реда с транзакцията, която искате да проверите.Заменете
<LINENO>с номера на реда точно след транзакция, за да видите нейния ефект. -
Проверка на съвпадението на партиди: Инструментът
bea checkвалидира целия ви файл. Той ще улови всички грешки при осчетоводяване, като например нееднозначни съвпадения на партиди в режимSTRICT.