Introduction to Ledger
Getting Started with Ledger
Since changing jobs, moving states, renting an apartment, and cohabiting for the first time all in the same month, I’ve been interested in understanding how my money tends to come in and go out. There are many tools available for this, all of them with different focuses and purposes. Some are great at ‘envelope budgeting’ — putting away a fraction of each paycheck into holiday, car, and bill funds — while others try to work well with your existing bank account, or your tax agent. I’d looked at these options in the past, but their slick interfaces felt too coddling, hiding details and thereby losing the value of tracking finances in the first place.
Being comfortable with the command line, I was naturally drawn to the notion of Plain Text Accounting. This is where you create a ‘journal’ of expenses, using a form of double-entry accounting, and define cost centres where you money goes. This to me had the advantages of:
- Ability to version control: I can keep this in Git so I can’t muck it up too badly;
- Transferrable format: I can use more than one application to read these files, if my current one stops being maintained;
- Accessible format: I can write my own tools if I want to do something unavailable today;
- Cheap: plenty of open-source software exists today to manipulate these plain text journals.
I spent a week playing around with the different offerings, and ultimately settled on hledger. What follows is a guide geared to using hledger
, but widely applicable to other plain text accounting programmes, as the syntax is broadly similar.
Starting Out: Your First Transaction
One of the most confusing aspects of using hledger
was just starting out — I had no idea how to notate existing wealth using its double-entry system. It turns out, this is straightforward. You take your equity and transfer it to your assets. If this is confusing, just do it once, consider it a magical incantation, and forget about it. You never have to think about this again.
2018/07/01 * Opening balances
equity:opening balances -$100,000.00
assets:anz:checking $20,000.00
assets:anz:savings $80,000.00
To view your balance statement you run the command hledger bs
, and get:
║ 2018/03/01
══════════════╬═════════════
Assets ║
──────────────╫─────────────
assets ║ $100,000.00
anz ║ $100,000.00
checking ║ $20,000.00
savings ║ $80,000.00
──────────────╫─────────────
║ $100,000.00
══════════════╬═════════════
Liabilities ║
──────────────╫─────────────
──────────────╫─────────────
║
══════════════╬═════════════
Net: ║ $100,000.00
All regular transactions have a negative and a positive line: in this instance, we ‘took’ from our equity, and we ‘gave’ to our checking and savings accounts. Similarly, when you go to the supermarket, you will ‘take’ from your wallet, and ‘give’ to your supermarket expenses account.
Journalling Your Everyday Transactions
A Single Transaction
To model a single transaction as in the supermarket, we write something similar to the following:
2018/03/01 ! WOOLWORTHS 3001 | Bread and cheese
expenses:supermarket $7.94
liabilities:anz:credit card -$7.94
To view our new balance statement we run the command hledger bs
, and get:
║ 2018/03/01
═════════════════╬═════════════
Assets ║
─────────────────╫─────────────
assets ║ $100,000.00
anz ║ $100,000.00
checking ║ $20,000.00
savings ║ $80,000.00
─────────────────╫─────────────
║ $100,000.00
═════════════════╬═════════════
Liabilities ║
─────────────────╫─────────────
liabilities ║ $7.94
anz ║ $7.94
credit card ║ $7.94
─────────────────╫─────────────
║ $7.94
═════════════════╬═════════════
Net: ║ $99,992.06
Transaction Notation
You may find it useful when entering transactions to store the payee’s name. This is the information before the pipe (|) in the supermarket example above. If you’d simply like a description of the transaction, omit the pipe character and simply write a description after the date.
You may also find it useful to have a distinction between ‘confirmed’ and ‘pending’ transactions. I use this for credit card authorisations, pending transactions that are yet to clear. Pending transactions are marked with an exclamation mark; confirmed transactions are marked with an asterisk.
Buying a Few Rounds (Multiple expenses at the same location on the same day)
2018/03/02 ! BEER N CO | Beverages
expenses:drinks $30.00
expenses:drinks $30.00
expenses:drinks $30.00
liabilities:anz:credit card -$90.00
To view our new balance statement including our supermarket run and some beers, we run the command hledger bs
, and get:
║ 2018/03/01
═════════════════╬═════════════
Assets ║
─────────────────╫─────────────
assets ║ $100,000.00
anz ║ $100,000.00
checking ║ $20,000.00
savings ║ $80,000.00
─────────────────╫─────────────
║ $100,000.00
═════════════════╬═════════════
Liabilities ║
─────────────────╫─────────────
liabilities ║ $97.94
anz ║ $97.94
credit card ║ $97.94
─────────────────╫─────────────
║ $97.94
═════════════════╬═════════════
Net: ║ $99,902.06
More Advanced Features of Ledger
Your Friends Owe You for Tickets
Every now and then, you will buy some items for people to partially pay you back. For example, going to a show together. This can easily be expressed in the following format:
2018/03/03 ! LAUGHALOT INC | Comedy tickets
expenses:entertainment $50.00
assets:accounts receivable $50.00
liabilities:anz:credit card -$100.00
To view our new balance statement we run the command hledger bs
, and get:
║ 2018/03/03
═══════════════════════╬═════════════
Assets ║
───────────────────────╫─────────────
assets ║ $100,050.00
accounts receivable ║ $50.00
anz ║ $100,000.00
checking ║ $20,000.00
savings ║ $80,000.00
───────────────────────╫─────────────
║ $100,050.00
═══════════════════════╬═════════════
Liabilities ║
───────────────────────╫─────────────
liabilities ║ $197.94
anz ║ $197.94
credit card ║ $197.94
───────────────────────╫─────────────
║ $197.94
═══════════════════════╬═════════════
Net: ║ $99,852.06
Medicare Rebate
For the Australians, you will be familiar with getting a partial rebate for your healthcare. Here is how I find it useful to express:
2018/03/04 * DOCTOR&DOCTOR | Doctor checkup
expenses:health $22.00
liabilities:anz:credit card -$97.00
assets:accounts receivable $75.00
2018/03/04 ! EFTPOS MEDICARE BENEFIT | Medicare Rebate
assets:accounts receivable -$75.00
assets:anz:checking $75.00
To view our new balance statement we run the command hledger bs
, and get:
║ 2018/03/04
═══════════════════════╬═════════════
Assets ║
───────────────────────╫─────────────
assets ║ $100,125.00
accounts receivable ║ $50.00
anz ║ $100,075.00
checking ║ $20,075.00
savings ║ $80,000.00
───────────────────────╫─────────────
║ $100,125.00
═══════════════════════╬═════════════
Liabilities ║
───────────────────────╫─────────────
liabilities ║ $294.94
anz ║ $294.94
credit card ║ $197.94
credit card black ║ $97.00
───────────────────────╫─────────────
║ $294.94
═══════════════════════╬═════════════
Net: ║ $99,830.06
Shares/Non-Cash assets
Structure
To keep things simple, let’s store your shares in an account just called shares. We’ll assume that there is some nominal brokerage fee, and that yourkeep the money to buy your shares in a separate brokerage account called cmc (after the share brokers).
2018/03/05 * 60 Vanguard (VAS) ASX300 shares ; shares:
assets:shares 60 VAS @ $60.00
expenses:investments:brokerage $11.00
assets:cmc
Now when we run out balance statement query, we’re shown that we have $96,514.00 in assets, as well as 60 VAS shares. This is informative, but not very useful for knowing our assets on a day-to-day basis. For that, we need to know the prices of all of our shares.
Note also that I’ve added a comment — text after a semi-colon in the transaction description — that will come in handy later on.
We can introduce a lookup file which tells us the value of one VAS share at a point in time. This can be done in the one ledger file, but it can be more useful to create a new file called something like prices.ledger, and make reference to this in the original ledger file. For example, I do the following:
include ~/.prices.hledger
In the prices file, we simply assert the date the price was looked up, and how much the share is worth with:
P 2018/03/05 VAS $60.00
Useful tools
I like to retrieve end-of-day pricing for my stocks. So, I download prices at 5pm each weekday.
My crontab has the following line:
~0 17 * * 1-5 ~/bin/stocks.sh >> ~/.prices.hledger
Let’s say I have positions in the ASX’s NDQ and VAS indexes. Then my ~/bin/stocks.sh
would be:
#!/bin/bash
STOCKS=(NDQ.AX VAS.AX)
count=0
for i in "${STOCKS[@]}"
do
string="P $(date +%Y/%m/%d) "
string+=$(echo ${i} | sed -E "s/\..*$//")
price="$"
price+=$(~/bin/ticker.sh "${STOCKS[count]}" | cut -c 18- | sed -E 's/^\s*([0-9\.]+).*/\1/')
string+=" $price"
echo "$string"
count=$(( $count + 1 ))
done
ticker.sh has been modified only slightly to retrieve prices from the Australia Yahoo! API (i.e., by setting API_ENDPOINT="https://query1.finance.yahoo.com/v7/finance/quote?lang=en-US®ion=AU&corsDomain=au.finance.yahoo.com"
in the script).
Useful hledger
Commands
Having my end-of-day figures, I can easily run the following commands to
Estimate total share value
hledger reg tag:"shares" assets:shares -V
2018/03/05 60 Vanguard.. assets:shares $3,600.00 $3,600.00
Estimate total share value increase
hledger reg tag:"shares" -V not:expenses
The total value will be the output of the last line. For example, let us assume after some time has passed, the following entry is made in the ledger:
P 2018/05/05 VAS $70.00
That is, the price of the stock VAS
was $70.00 on 2018/05/05. We then run the command: hledger reg tag:"shares" -V not:expenses
:
2018/03/05 60 Vanguard.. assets:shares $4,200.00 $4,200.00
assets:cmc $-3,611.00 $589.00
This tells us that, after costs, we have made an (unrealised and untaxed) profit of $589.00
Conclusion
Plain text accounting is a great way to simply keep track all of your expenses, but can also be used for more complicated assets, such as equities. hledger
is a straightforward way to get powerful summary information once you’ve assiduously kept track of only a few transactions.
The project is still very much underway, with downloads available here, and discussion taking place here.