Artificial truth

archives | latest | homepage | atom/rss/twitter

The more you see, the less you believe.

Accounting for the simple minds with plain text accounting
Fri 01 December 2017 — download

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, like hledger 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 :, like Expenses: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

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

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

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

       -3.330000 BTC  Income:Salary
       -3.330000 BTC

        1.070000 BTC  Expenses
        0.020000 BTC    Drinks
        1.000000 BTC    House:Rent
        0.050000 BTC    Resto
        1.070000 BTC

       -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.