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.

Print

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

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:

Documentation

The official documentation is available: