I'm lazy, and I spent my (awful) accounting courses at school hacking on radare2/sleeping/arguing about game theory, 5 years ago, so I do suck at counting and managing my money.
Some people find this boring, but I think that it's nice to be able to see trends of what you're doing with your money, how much you're throwing in your rent, how much into alcohol, … and to be honest, I do find it relaxing: because each error you make is painful to spot, you're forced to focus on what you're doing, and to clear every other thoughts. A bit like shaving with a straight razor.
The quest
There are a lot of available (free) software to do accounting, with fancy features and nice interfaces, like gnucash and homebank (asking me to disable my ad-blocker, and hosted on some ghetto free-hoster), but I wanted something as simple as possible.
I asked various people in charge of money in open-source projects, and it seems that everyone is using hledger (a rewrite in haskell of ledger, with less features) because it's simple and usable, allowing to quickly get the accounting done and go back to writing code.
It has several cool features:
- A command-line interface, with auto-completion to input your data.
- Import capabilities from various formats.
- It just works: no need to configure anything, or to go though a shitload of
different menus: just write your operation in your favourite text editor,
or interactively with
ledger-cli
. - Its storage format is plain-text: easy to edit, easy to backup, easy to read, easy to version, easy to parse, hard to fuck up, …
- The
ledger
binaries are providing simple and powerful queries/display capabilities, likehledger balance --quarterly income expenses -E
,hledger incomestatement
, … - It can deal in a simple way with multiple currencies without any hassle: just append the right currency trigram after the amounts.
Looks wonderful, time to read its documentation.
Double-entry bookkeeping system
Hledger (along with ledger, beancount, …) are double-entry bookkeeping system, and it's apparently what everyone is using in the accounting world.
As wikipedia says:
In the double-entry accounting system, at least two accounting entries are required to record each financial transaction. These entries may occur in asset, liability, equity, expense, or revenue accounts. Recording of a debit amount to one or more accounts and an equal credit amount to one or more accounts results in total debits being equal to total credits for all accounts in the general ledger. If the accounting entries are recorded without error, the aggregate balance of all accounts having Debit balances will be equal to the aggregate balance of all accounts having Credit balances.
It boils down to "if something comes in, something comes out".
Using it
Hledger (and plain-text accounting in general) uses a specific terminology:
- Account: A label that represent a source or a destination for you money,
nestable with
:
, likeExpenses:home:internet
. It's not the same than your bank account, it's simply a label. - Journal: A journal is a file in ledger format, that contains transactions. I'm using a different one per year.
- Transaction: A financial event entered into a journal.
- Posting: A posting is a line in your transaction, like adding 0.1 BTC to
your gasoline
Expenses:shopping
account
Smart people are using those top-level accounts, so I'm trying to use the same scheme:
- Assets: where money sits (your bank accounts)
- Equity: the real value of your property (the money that comes "out of nowhere" when you're starting to do your accounting: how much money do you have on your back account, …)
- Expenses: where money goes (stuff that you buy)
- Income: where money comes from (your salary)
- Liabilities: money you owe (your debts)
The magic rule is that Assets = Liabilities + Equity
; each time you add money
to an account, you have to remove it from an other one.
The syntax of a journal file is simple:
; Comment
Date State Description Extended_description
Account1 Amount1
Account2 Amount2
AccountN
The State
can either be *
indicating that the transaction is done, or !
if it's pending.
For example:
2017-06-02 * "Fancy diner" "at Le Fouquet's"
Expenses:Resto 0.05 BTC
Expenses:Drinks 0.02 BTC
Assets:Crypto:BTC
2017-06-01 * "Rent"
Expenses:House:Rent 1 BTC
Assets:Crypto:BTC -1 BTC
2017-05-30 * "Salary"
Assets:Crypto:BTC 3.33 BTC
Income:Salary -3.33 BTC
; Opening my BTC account
2017-04-01 * "Opening balance"
Assets:Crypto:BTC 0.017075 BTC
Equity:Opening-Balances:BTC
You don't need to enter the amount in one of the account, since ledger can automatically compute it by itself. Most of the time, there are only two operations per transaction, but you can have as much as you want.
If you're a vim user like me, you might want to use this plugin to have autocompletion, syntax highlighting, linting, …
Getting info about your spendings
The register
command is useful to get a overview of your postings:
$ hledger register
2017/04/01 "Opening balance" Assets:Crypto:BTC 0.017075 BTC 0.017075 BTC
Equity:Opening-Balances:BTC -0.017075 BTC 0
2017/05/30 "Salary" Assets:Crypto:BTC 3.330000 BTC 3.330000 BTC
Income:Salary -3.330000 BTC 0
2017/06/01 "Rent" Expenses:House:Rent 1.000000 BTC 1.000000 BTC
Assets:Crypto:BTC -1.000000 BTC 0
2017/06/02 "Fancy diner" "at Le Fouquet's" Expenses:Resto 0.050000 BTC 0.050000 BTC
Expenses:Drinks 0.020000 BTC 0.070000 BTC
Assets:Crypto:BTC -0.070000 BTC 0
I also do like the incomestatement
command to have a summary:
$ hledger incomestatement
Income Statement
Revenues:
-3.330000 BTC Income:Salary
--------------------
-3.330000 BTC
Expenses:
1.070000 BTC Expenses
0.020000 BTC Drinks
1.000000 BTC House:Rent
0.050000 BTC Resto
--------------------
1.070000 BTC
Total:
--------------------
-2.260000 BTC
And finally, the balance
one.
$ hledger balance --monthly
Balance changes in 2017q2:
|| 2017/04 2017/05 2017/06
=============================++===========================================
Assets:Crypto:BTC || 0.017075 BTC 3.330000 BTC -1.070000 BTC
Equity:Opening-Balances:BTC || -0.017075 BTC 0 0
Expenses:Drinks || 0 0 0.020000 BTC
Expenses:House:Rent || 0 0 1.000000 BTC
Expenses:Resto || 0 0 0.050000 BTC
Income:Salary || 0 -3.330000 BTC 0
-----------------------------++-------------------------------------------
|| 0 0 0
All commands can of course take a reasonable number of parameters (--monthly
,
--file
, --begin
, --end
, …).
The fancy web interface
Ledger and hledger are great, but if you're using beancounter, you can use the amazing fava web interface (with a demo here)! Fortunately, the beancount format is the ledger one, but more strict, so the two are compatible.
For example, in beancount, you have to actually open (meaning that you can close) bank accounts, where in (h)ledger, they'll be automatically detected. This might sound like a burden, but I do like to be forced to do thing in a proper way: this helps me to reduce my number of mistakes.
Resources
- A big article like this one, but way better.
- A even bigger article, great too.