Concept of Lots
One often needs to know that an item 'bought' in one transaction is the same one 'sold' in a different transaction. Lots are used to make this association. A single lot holds all of the splits that involve the same item. A lot is typically formed when an item is bought, and is closed when the item is sold. A lot need not be a single item, it can be a quantity of the same thing e.g. 500 gallons of paint (sold off a few gallons at a time).
Lots are required to correctly implement invoices, inventory, depreciation and stock market investment gains. See the Lots Architecture & Implementation Overview for more details, or src/doc/lots.txt for technical implementation documentation.
A lot is "closed" when the number of items in the lot has gone to zero. It is very easy to compute the gains/losses for a closed lot: it is the sum-total of the values of the items put into/taken out of the lot. Gains on still-open lots can be computed by pro-rating the purchase prices.
Lots are nothing more than a collection or grouping of splits in an account. All of the splits in a lot must belong to the same account. Lots have an implicit "opening date": the date of the earliest split in the lot. The "close date" is the date of the split that brought the lot item balance down to zero.
Lots play an important role in the calculation of the average cost of an investment. By eliminating closed lots, which include the stocks that were already sold, and sold portions of the open lots, the average cost calculation will take into consideration only the remaining portions of the open lots. This will result in an accurate value for the remaining stock portfolio.
The GnuCash "Scrub" menu entry attempts to automatically classify all splits into lots, using a FIFO policy. The scrubber will also automatically compute gains/losses for each lot.
There is a simple GUI for looking at the list of lots, and for viewing and editing the contents of a lot.
The GUI allows operations like joining lots, or splitting lots by hand, for cases when automatic Lots recognition gets it wrong.
Workings of the UI are demonstrated on a simple case of an investment fund - Lots GUI.
Refining the concept of lots
Referring to /src/doc/lots.txt there are several issues with the current concept of lots. For example there are problems with stock transactions. Additional concepts to eliminate the known issues:
Currently, the stock split druid simply creates a transaction at the date of the split that modifies the share count to reflect the new total shares. In most cases, this is probably fine. However, when combined with capital gains tracking, it can cause problems in differentiating between short and long term gains. For example, let's suppose I buy 100 shares of XYZ on January 1, 2008. XYZ splits 2 for 1 on January 1, 2009. I sell 200 shares of XYZ on July 1, 2009. The current lot system will make two matches: 100 shares from the lot on 1/1/08, and 100 shares from the "lot" created on 1/1/09. This is incorrect, since obviously the shares that were sold were all purchased on January 1, 2008. Either the lot scrubber needs to take splits into account, or splits need to be implemented as retroactive modifications to outstanding lots (or in theory all previous buys/sells for that security).
This is partly proposes an additional concept to the current implementation.
An account is marked as "lots account" or not. If it is a account in which lots should be tracked it is marked as "lot account" and all splits in it will need to belong to a lot.
For splits of incoming transactions a new lot ID is generated automatically.
For splits of outgoing transactions the user has to choose which lots to transfer if he did not preselect a method like FIFO or LIFO for this account.
Transactions between two "lot accounts" means "transferring lots". That implies to carry on the opening date:
The source lot(s) in the originating account needs to be chosen as in all outgoing transactions. The split in the destination lot account gets the same lot ID and "opening date" as in the originating account. If the lot already existed (subsequent transfers) this simply adds the new split to that lot.
Handling of Gains/Losses
current "double-balance algorithm"
The computation of (Realized) Gains/Losses is performed automatically by the lot "scrub" routines, using a "double-balance" algorithm. Every split has two numbers associated with it: an "amount", which is the number of items that a split describes, and the "value", which is the cost of those items. In a closed lot, the grand-total amount of items in the lot is zero: the number of items bought equals the number of items sold; thus the amount-balance is zero. But since the purchase/sale of the items in the lot typically happen at different prices, there will typically be a gain/loss. This gain/loss is the grand-total value of all the items in the lot (total costs minus total income).
In order to properly account for the gains/losses, an "adjusting split" is added that brings the total gains/losses back to exactly zero (this is the second "balance" of "double balance"). This adjusting split will have an amount of zero (no items are involved) but have a non-zero value (equal to the total gain/loss). This split can then participate in a "gains transaction" which records the gains in another account. Thus, for example, if you record $300 in your bank account due to the purchase and then the sale of some item, the "gains transaction" will record $300 in income in an income account. Thus, the change in the bank balance is always reflected by an equal change in income, assuring that the books are balanced.
Refining the concept of lots
For one the "double balance" as described above and in /src/doc/lots.txt but has issues. (also mentioned therein)
Additionally implementing such "adjusting transactions" would mean introducing fixed assumptions into the transaction data because unrealized gains or losses will always remain estimates or are uncertain. On the other hand "double balancing" isn't really needed. Unrealized gains/losses should be handled just by reports and policy use price database/purchase price etc.) as described below. Realized gains need to be handled by policy and transactions. This is done for example (tax simplified) by debiting your cash account the full sales price, crediting an inventory account the purchase price and credit the difference to the sales price to an income account.
Handling of Unrealized Gains/Losses
Unrealized gains or losses are a matter of your point of view. Depending in which commodity you want your reports to show, all other commodities you own will have an unrealized value for you. They have a price risk. The price of stocks, foreign currency, etc. will change over time. Some values like stocks denominated in foreign currency even have a double price risk.
Stocks do not need to be treated differently than other commodities. Only realized gains or losses are real and should therefore go into the accounts permanently (crediting an income account). Unrealized gains should only be calculated dynamically.
Unrealized gains or losses of stocks are available with the price database just like with multi currencies handling. It's the "Total (Report)" column in the Accounts tab minus the buying price. In a "lot account" with a default calculating method like FIFO set even taxes or performance could be estimated accordingly.