Inventory Management in Beancount
Beancount's inventory system is a powerful feature for tracking assets that are bought and sold over time, such as stocks, mutual funds, or foreign currencies. It allows for precise tracking of cost basis, which is essential for calculating capital gains and understanding portfolio performance. This tutorial covers the core mechanics of managing inventories in your ledger.
Core Concepts
At its heart, inventory management revolves around tracking positions. A "position" is simply an amount of a commodity held in an account. Beancount distinguishes between two fundamental types of positions.
Position Types
-
Simple Position (No Cost): This is a standard balance posting. It represents an amount of a commodity without any associated acquisition cost. It's suitable for cash or simple balance assertions.
Assets:Bank:Checking 100.00 USD
-
Position with Cost Basis: This type of position includes not only the number of units and the commodity but also the cost at which it was acquired. This is the foundation of inventory tracking. The cost is specified within curly braces
{}
.Assets:Invest:VTSAX 10 VTSAX {100.00 USD, "lot-1"}
In this example, we hold 10 units of
VTSAX
. Each unit was acquired at a cost of $100.00 USD. This specific batch of shares is identified as a "lot."
Inventory Operations
There are two primary operations you can perform on an inventory:
-
Augmentations (Adding to inventory): When you buy a commodity, you augment your inventory. You create a new lot with a specific number of units and a cost basis.
2024-01-15 * "Buy shares"
Assets:Invest:STOCK 50 STOCK {25.00 USD, "lot-1"}
Assets:Bank:Checking -1250.00 USDHere, we buy 50 units of
STOCK
at a per-unit cost of $25.00 USD. This creates a lot in theAssets:Invest:STOCK
account. -
Reductions (Removing from inventory): When you sell a commodity, you reduce your inventory. You must specify which lot you are selling from. This is done by providing matching information in the curly braces.
2024-01-20 * "Sell shares"
Assets:Invest:STOCK -25 STOCK {25.00 USD}
Assets:Bank:Checking 625.00 USDIn this transaction, we are selling 25 units of
STOCK
from the lot that was purchased at $25.00 USD per unit.
Booking Methods
When you reduce an inventory, Beancount needs a rule to decide which specific lot to pull from if multiple lots match or if the match is ambiguous. This rule is called the "booking method." You can set a default method for your entire file or specify one for each account.
1. STRICT (Default)
The STRICT
method is the default and safest booking method. It enforces explicit and unambiguous matching.
2024-01-01 open Assets:Invest:STOCK "STRICT"
- Requires Exact Lot Match: You must provide enough information in the reduction posting (
{...}
) to uniquely identify the lot being sold. - Errors on Ambiguous Matches: If the information provided matches multiple lots, Beancount will raise an error, forcing you to be more specific.
- Exception: If a reduction posting exactly removes the total number of units held in an account, an empty cost specifier (
{}
) is allowed.
2. FIFO (First-In, First-Out)
The FIFO
method automatically books reductions against the oldest available lots first.
2024-01-01 open Assets:Invest:STOCK "FIFO"
- Automatic Resolution: It resolves ambiguity by selecting the oldest matching lots.
- Chronological Matching: This is a common accounting method where you assume you are selling the assets you have held the longest. This is the required method for tax purposes in many countries.
3. LIFO (Last-In, First-Out)
The LIFO
method is the opposite of FIFO. It books reductions against the newest available lots first.
2024-01-01 open Assets:Invest:STOCK "LIFO"
- Reverse Chronological Order: It selects the most recently acquired lots that match the reduction criteria.
- Tax Optimization: In some jurisdictions, this method can be used for tax optimization, for instance, by selling the shares with the highest cost basis first to minimize capital gains.
4. NONE
The NONE
method disables lot matching entirely.
2024-01-01 open Assets:Invest:STOCK "NONE"
- No Lot Matching: Beancount does not attempt to match reductions to augmentations.
- Allows Mixed Signs: This allows an account to hold both positive and negative balances of the same commodity simultaneously. This behavior is similar to how the Ledger CLI tool handles commodities.