Към основното съдържание

Управление на инвентара

Научете как ефективно да управлявате инвентара в Beancount, като се фокусирате върху проследяването на активи като акции и валути, разбирането на цената на придобиване и изчисляването на капиталови печалби за по-добро представяне на портфейла.

Системата за инвентар на Beancount е мощна функция за проследяване на активи, които се купуват и продават във времето, като акции, взаимни фондове или чуждестранни валути. Тя позволява прецизно проследяване на цената на придобиване, което е от съществено значение за изчисляване на капиталови печалби и разбиране на представянето на портфейла. Този урок обхваща управлението на инвентара във вашата счетоводна книга.

Основни концепции

В основата си управлението на инвентара се върти около проследяването на позиции. „Позиция“ е просто количество от дадена стока, държано в дадена сметка. Beancount прави разлика между два основни типа позиции.

Видове позиции

  1. Проста позиция (без цена на придобиване): Това е стандартен балансов запис. Той представлява количество от стока без свързана цена на придобиване. Подходяща е за парични средства или прости балансови проверки.

    Assets:Bank:Checking      100.00 USD
  2. Позиция с цена на придобиване: Този тип позиция включва не само броя на единиците и стоката, но и цената, на която е била придобита. Това е основата на проследяването на инвентара. Цената е посочена в гъвкави скоби {}.

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

    В този пример държим 10 единици от VTSAX. Всяка единица е била придобита на цена от $100.00 USD. Тази конкретна партида акции е идентифицирана като „партида“ (lot).

Операции с инвентара

Има два основни вида операции, които можете да извършите върху инвентара:

  1. Увеличения (добавяне към инвентара): Когато купувате стока, вие увеличивате инвентара си. Вие създавате нова партида с конкретен брой единици и цена на придобиване.

    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.

  2. Намаления (премахване от инвентара): Когато продавате стока, вие намалявате инвентара си. Трябва да посочите от коя партида продавате. Това се прави, като предоставите съответстваща информация в гъвкавите скоби.

    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:Gains

Beancount докладва 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:FifoFIFOпартида А, 2024-01-10$100.00$500.0010 @ $120.00, 10 @ $90.00
Assets:Broker:LifoLIFOпартида С, 2024-03-10$90.00$600.0010 @ $100.00, 10 @ $120.00
Assets:Broker:HifoHIFOпартида Б, 2024-02-10$120.00$300.0010 @ $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: Анотация, която записва пазарна цена по време на транзакция. Използва се за валутни конвертирания или за отбелязване на пазарната стойност на определена дата.

Ето трите сценария:

  1. Анотация за цена (конвертиране): Използвайте @ за конвертиране от една валута в друга.

    Assets:Forex     1000 USD @ 0.85 EUR
  2. Цена на придобиване (придобиване): Използвайте {} при закупуване на актив, за да установите неговата себестойност.

    Assets:Invest    10 STOCK {100.00 USD}
  3. И две те (продажба с запис на цената): При продажба на актив, използвайте {}, за да идентифицирате партидата, която се продава, и @, за да запишете продажната цена. Това позволява автоматично изчисляване на капиталови печалби.

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

    Този запис продава 10 STOCK от партидата, която е струвала $100.00 за брой, на продажна цена от $105.00 за брой.

Правила за използване на цената

  1. Анотациите за цена (@) не влияят на това коя партида се осчетоводява. Съвпадението на партиди се извършва изключително от цената на придобиване ({}) и метода на осчетоводяване на сметката.
  2. Символът @ се използва само за:
  • Валутни конвертирания.
  • Записване на пазарната стоойност на актив към момента на транзакцията.
  • Предоставяне на продажната цена за изчисляване на капиталови печалби.

Конфигурация

Можете да конфигурирате методите на осчетоводяване глобално или на ниво отделна сметка.

Глобален метод на осчетоводяване

Можете да зададете метод на осчетоводяване по подразбиране за целия си файл на 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"

Най-добри практики

  1. Организация на инвентара: За да поддържате счетоводната си книга чиста и проста, силно се препоръчва да използвате отделни сметки за всяка уникална стока, която притежавате, и да ограничите всяка от тях до тази стока в нейната директива 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 да отхвърли случайно публикуване, вместо мълчаливо да смеси два инвентара.

  2. Управление на партиди:

  • Използвайте смислени етикети за партидите, особено за конкретни транзакции като събиране на данъчни загуби или служителски акционерни грантове.

    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%
  1. Отстраняване на грешки: Ако срещнете грешки или неочаквано поведение, Beancount предоставя инструменти за проверка на състоянието на вашия инвентар.
  • Проверка на състоянието на инвентара: Използвайте bea doctor context main.beancount 42, за да проверите транзакцията на ред 42, включително нейните публикации и засегнатите салда по сметки. Заменете името на файла и номера на реда с транзакцията, която искате да проверите.

    Заменете <LINENO> с номера на реда точно след транзакция, за да видите нейния ефект.

  • Проверка на съвпадението на партиди: Инструментът bea check валидира целия ви файл. Той ще улови всички грешки при осчетоводяване, като например нееднозначни съвпадения на партиди в режим STRICT.

Източник: https://beancount.io/bg/docs/Basics/inventories