Система обліку запасів Beancount — це потужна функція для відстеження активів, які купуються та продаються з плином часу, таких як акції, пайові фонди або іноземна валюта. Вона дозволяє точно відстежувати собівартість, що є важливим для розрахунку приросту капіталу і розуміння результатів портфеля. Цей посібник охоплює основні механізми управління запасами у вашому журналу.
Основні поняття
В основі управління запасами лежить відстеження позицій. "Позиція" — це просто кількість товару, що знаходиться на рахунку. Beancount розрізняє два фундаментальні типи позицій.
Типи позицій
-
Проста позиція (без вартості): Це стандартне записування балансу. Вона представляє кількість товару без пов’язаної вартості придбання. Підходить для готівки або простих затверджень балансу.
Assets:Bank:Checking 100.00 USD -
Позиція з собівартістю: Цей тип позиції містить не лише кількість одиниць та товар, але й вартість, за якою він був придбаний. Це основа відстеження запасів. Вартість вказується у фігурних дужках
{}.Assets:Invest:VTSAX 10 VTSAX {100.00 USD, "lot-1"}У цьому прикладі ми маємо 10 одиниць
VTSAX. Кожна одиниця була придбана за вартістю $100.00 USD. Ця конкретна партія акцій ідентифікується як "лоти".
Операції з запасами
Існують дві основні операції, які ви можете виконувати з запасами:
-
Збільшення (додавання до запасів): Коли ви купуєте товар, ви збільшуєте свої запаси. Ви створюєте новий лот із заданою кількістю одиниць та собівартістю.
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 за одиницю.
Методи резервування
Коли ви зменшуєте запас, Beancount потребує правила для вибору конкретного лоту, якщо кілька лотів підходять для зменшення. Це правило називається "метод резервування". Ви можете встановити його за замовчуванням для всього файлу через опцію або надати окремому рахунку власний метод у директиві open.
Beancount 3.2.3 приймає сім назв методів: STRICT (типовий), STRICT_WITH_SIZE, NONE, FIFO, LIFO, HIFO та AVERAGE. Шість із них реалізовані; 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 на одних і тих же партіях
Три методи відрізняються лише тоді, коли найстаріша, найнова та найдорожча партії — це три різні партії. Цей журнал саме так організовано — партія A найстаріша, партія C найнова, і середня партія B найдорожча — після чого продають 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 | партія A, 2024-01-10 | $100.00 | $500.00 | 10 @ $120.00, 10 @ $90.00 |
Assets:Broker:Lifo | LIFO | партія C, 2024-03-10 | $90.00 | $600.00 | 10 @ $100.00, 10 @ $120.00 |
Assets:Broker:Hifo | HIFO | партія B, 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.