Introduction
This is the Ledger Cookbook, a collection of recipes which describe how to use Ledger's Plain-Text Accounting syntax for common situations a user may encounter.
If you need a specific recipe or would like to share one, please create an issue in the source repository or write the recipe and submit a pull request.
Categories
A good starting point for categories is the Classification of Individual Consumption According to Purpose (COICOP), published by the Department of Economic and Social Affairs of the United Nations Secretariat.
Quote from the document:
The Classification of Individual Consumption According to Purpose (COICOP) is the international reference classification of household expenditure. The objective of COICOP is to provide a framework of homogeneous categories of goods and services, which are considered a function or purpose of household consumption expenditure.
COICOP is an integral part of the System of National Accounts (SNA), but it is also used in several other statistical areas, such as: household expenditure statistics based on household budget surveys and the analysis of living standards; consumer price indi- ces; international comparisons of gross domestic product (GDP) and its component expenditures through purchasing power parities; and statistics relating to culture, sports, food, health, and tourism.
The idea of classifying household consumption expenditure at the international level dates back to the year 1923 and resulted three years later into the first, still very broad classification of household expenditure elaborated by the International Confer- ence of Labour Statisticians. When the first version of the SNA was published in 1953, it contained also a classification of private consumption expenditure, which then evolved with each new version of the SNA.
Available at:
Register
Recipes for the Register reports
Full Running Total
You can list the transactions since the last month while displaying the full running total.
ledger reg checking -d "d>=[last month]"
The parameter -d EXPR
or --display EXPR
will limit the display to the postings specified in the EXPR, while the calculations will still include all the records.
The command above will result in a report that only displays the transactions since the last month, yet displaying the cummulative running total for all dates.
Example:
For the transactions
2022-12-30 Allowance
Income:Allowance
Assets:Cash 150 EUR
2023-01-01 Party
Expenses:Entertainment
Assets:Cash -100 EUR
2023-01-02 Coffee & donuts
Expenses:Entertainment
Assets:Cash -10 EUR
the register report for all dates displays
22-Dec-30 Allowance Assets:Cash 150 EUR 150 EUR
23-Jan-01 Party Assets:Cash -100 EUR 50 EUR
23-Jan-02 Coffee & donuts Assets:Cash -10 EUR 40 EUR
But with the -d
filter ledger reg cash -d "date>=[2023-01-01]"
it will list
23-Jan-01 Party Assets:Cash -100 EUR 50 EUR
23-Jan-02 Coffee & donuts Assets:Cash -10 EUR 40 EUR
Note that the running total for the account is correct.
This may be useful for checking the transactions for a specific period on an account that has been active a long time, i.e. comparing bank statements.
The print
command outputs the transactions the way they are entered in the journal. The output is automatically formatted. It will not display the balance assertions, for example.
The argument --raw
can be used to output the transactions exactly like they were entered, including all the left-out bits.
This command, like other report commands, accepts query parameters which can be used to filter down transactions.
The advantage of this command is that the full transaction is displayed in the output, together with any comments. This can be used to parse the output by a software tool or just provide the full information to the user.
Example
The command
ledger print "expr" "note =~ /apple/"
outputs
2021-10-24 Local Market
; Apple Pencil 1
Expenses:InfoComm:Hardware 50.00 EUR
Assets:Cash
2021-12-26 Petra
; Apple headphones
Expenses:InfoComm:AudioVideo 5.00 EUR
Assets:Active:Cash EUR
2022-01-15 Giorgi
; Apple Lightning cables
Expenses:InfoComm:Electronics 8.00 EUR
Assets:Cash
Transactions
Specific Transfers
There is sometimes a need to identify transfers from a specific account (Checking) to another specific account (Liabilities:Credit Card). That is, we are looking for transactions of type:
2022-12-23 Transfer
Assets:Bank:Checking -100 EUR
Liabilities:Credit Card 100 EUR
It is a seemingly simple report, yet it is not so simple to produce. To achieve this, we need to to run two reports, for each of the accounts.
ledger print --raw Checking | ledger -f - --permissive reg Liabilities:Something
In case you get errors in transactions with balance assertions, the first command can be run separately to create an intermediary file.
ledger print --raw Checking > temp.ledger
Then comment-out the balance assertions and run the second report on this file.
ledger -f temp.ledger --permissive reg Liabilities:Something
This illustrates the general concept. The queries can be enhanced with the amount specifications, i.e. the amount on the Checking account is negative while the amount on the Liabilities account is positive, to indicate the direction of the money flow.
Search Comments
An expression
expr note =~ /REGEX/
is a regular expression that matches against a transaction’s note field. This searches all comments in the transaction, including comments on individual postings.
The query
ledger reg "expr" "note =~ /landline/"
will match all the three examples below
2014/1/29 Phone bill
Assets:Checking $50.00
Expenses:Phone $-50.00 ; landline bill
2014/1/29 Phone bill ; landline bill
Assets:Checking $50.00
Expenses:Phone $-50.00
2014/1/29 Phone bill
; landline bill
Assets:Checking $50.00
Expenses:Phone $-50.00
To search only posting comments, see Search posting comments.
Search Posting Comments
An expression
comment =~ /REGEX/
is a regular expression that matches against a posting’s comment field. This searches only a posting’s field, not the transaction’s note or comment field.
Example:
ledger reg "expr" "comment =~ /landline/"
will match
2014/1/29 Phone bill
Assets:Checking $50.00
Expenses:Phone $-50.00 ; landline bill
but will not match
2014/1/29 Phone bill ; landline bill
; landline bill
Assets:Checking $50.00
Expenses:Phone $-50.00
To search for transaction comments, see Search comments.
Lots
Basic Ledger's documentation on the use of Lots is in the Buying and Selling Stock section of the documentation.
Lots are used for the calculation of Capital Gain/Loss as they record the date and price of any lot of owned commodities. Usually the main reason for this is Tax Lot Accounting, or the governments' requirement to report Capital Gain/Loss and as it affects taxation.
See also the related page on Capital Gains.
Recipes
Lots Basic Use
This is an illustration on the use of Lots.
Lots are created automatically when a price is specified for a commodity.
2004-05-01 Stock purchase
Assets:Broker 50 AAPL @ $30.00
Expenses:Broker:Commissions $19.95
Assets:Broker $-1,519.95
This will create a lot of 50 units of AAPL, with the original cost of $30 per unit. The lot date is 2004-05-01.
The basic report is ledger balance Broker --lots
.
The lots are specified for the sale transaction:
2005-08-01 Stock sale
Assets:Broker -50 AAPL {$30.00} [2004-05-01] @ $50.00
Expenses:Broker:Commissions $19.95
Income:Capital Gains $-1,000.00
Assets:Broker $2,480.05
This transaction will precisely identify the lot to be sold and calculate the capital gains. For example, if you leave out the Capital Gains posting, the transaction will be reported as invalid by Ledger.
Lots, Sorting by Date
To sort the lots by date, the following command can be used on Linux:
ledger b --lots ass and vas_ax$ --no-total --flat | sort -t ' ' -k5
ledger -f file.dat bal account --lots | sort -t ' ' -k5
The expression below was created for this purpose but still has issues. Keeping it here for reference and a reminder.
ledger bal --lots "Account" -f myfile.dat \
-S 'lot_date(total) || date' -y "%Y-%m-%d"
This will sort on the lot date of the total, or the date if no lot date exists.
Capital Gains
Introduction
The calculation of the Capital Gains/Loss will depend on the method chosen for calculating the value of the holdings in an account.
Some standard ways of calculating the value include
- First In, First Out
- Average Cost Basis Method, Investopedia
- LIFO
- Hight-Cost and Low-Cost
- Specific Identification Method
Choosing a method will have a huge impact on the resulting amount and the tax liability.
Ledger Implementation
Ledger calculates Capital Gain/Loss based on the information contained in the Lots.
Reports
A gain/loss report is created by using -G
option.
For example:
ledger bal investments -G -X EUR
would show the balances report of the Investmens accounts, listing the gain/loss expressed in Euros.
Return of Capital
A company issues a Return of Capital event, returning the capital to the shareholders.
The returned funds are not income and therefore this is not a taxable event. But the dates need to be preserved to correctly calculate the capital gains/losses when the securities are disposed of in the future.
The event also adjusts the cost basis, affecting the price of the security.
Syntax
The syntax for this case is as follows:
2000-01-01 * Bought IPE
Assets:Investments:Broker:Shares:IPE 100 IPE {10.00 USD} [2000-01-01] @ 10.00 USD
Assets:Investments:Broker:Cash -1000.00 USD
2019-04-01 * Return of capital
Assets:Investments:Broker:Shares:IPE -100 IPE {10.00 USD} [2000-01-01] @ 5.00 USD
Assets:Investments:Broker:Shares:IPE 100 IPE { 5.00 USD} [2000-01-01] @ 5.00 USD
Assets:Investments:Broker:Cash 500.00 USD
Explanation
The first transaction is the original purchase of a security. It is used here for reference and comparison of the data points that need to be endered in the second transaction record.
In the first transaction we are using the full Lot syntax, explicitly specifying the date and the price although this is normally not necessary. The dates ([2000-01-01]
) are inferred from the transaction date and the price from the price syntax (@ 10.00 USD
). Here we are illustrating the example only.
The first transaction buys 100 units of IPE in the value of $1000.
The second transaction marks the Return of Capital event:
- 500 USD is returned to the investor
- 100 units of IPE, purchased at $10 is removed, "sold" at $5
- 100 unites of IPE added to the account with the same date and the price of $5
This results in
- $500 returned to the investor
- the remaining 100 units of IPE with the price of $5 have $500 total value
References
Reverse Stock Split
A Reverse Stock Split, per Investopedia, is a corporate action that consolidates the number of existing shares of stock into fewer (higher-priced) shares.
This reduces the number of shares outstanding and increases their price.
Example
For holdings acquired as
2016-09-28 Buy EMLC
Assets:Investments:Shares USD:EMLC 44 EMLC @ 19.10 USD
Expenses:Commissions 2 USD
Assets:Investments:Cash USD
A reverse stock split would be entered as
2018-10-26 Reverse Stock Split
; 1:2
Assets:Investments:Shares USD:EMLC -44 EMLC {19.10 USD} [2016-09-28]
Assets:Investments:Shares USD:EMLC 22 EMLC {38.20 USD} [2016-09-28]
Which replaces the holding of 44 shares with 22 shares of EMLC, effectively halving them. The date of the lot remains the same. The price doubles from 19.10 USD to 38.20 USD. The net balance in USD is the same.
Other Resources
More recipes can be found at the following locations, maintained by the Plain-Text Accounting community:
- Plain-Text Accounting Workshop, Colin Dean
- Ledger Wiki
- Plain-Text Accounting Wiki, Simon Michael
Documentation
The official documentation is available: