"Beancount: Introduction to plain text accounting."
, by 4eyes.Have you ever wondered what happened to those 50 euros you saw in your wallet yesterday, or has your significant other all of a sudden wanted to discuss the unrealized losses of your investments at the dining table? Then yes, you guessed it correctly, there are self-hosted solutions for those situations. They will not correct the financials mistakes you made, obviously, but they might help you navigate one of the most enjoyable aspects of adult life. Finance.
Types of finance programs
Jokes aside, it's not one of the favorite areas of self-hosting, but there are actually various types of programs to manage finances, just some projects don't have a lot of alternatives. I will try to explain some of those types.
- The most complex type is the plain text accounting programs. Beancount, ledger, and hledger are the big four. I mean, three... These are basically accounting programs that keep the data in plain text files, each with its own syntax and ecosystem. Obviously, they are not comparable with ERPs that are on the market but easily handle a household's or (very) small business' finances. They can get more capabilities with plugins and can also achieve the tasks mentioned in other categories, although maybe not perfectly. And since you keep the data in plain text, your data is not held hostage, and there is the possibility to switch from one to another. Though, I only used beancount, I can't really tell how difficult it is. I will talk more about bencount and fava later.
- Another type would be portfolio performance tools. As I said above, you can also analyze your investment portfolio or retirement fund with plain text accounting programs, the tools in this category are focused only this task. Portfolio Performance and Ghostfolio are the ones I know about.
- And the last category could be the budget management tools, where their main focus is where you spend your money and having that wake-up call when you realize what a financial black hole this hobby is. Firefly 3 and Actual are two examples.
Before going into detail with Beancount, let me explain a little bit what plain text account is.
Plain text accounting
So, what is plain text accounting? Here is the link: plaintextaccounting.org. Read it, and let me know if you have any questions. OK! For the lazy, I will put the definition here from the very same website, lazily and shamelessly. Plain text accounting is a way of doing bookkeeping and accounting with plain text files and scriptable, command-line-friendly software. That's it.
Plain text accounting programs take your transactions in simple text files as input, consume them, and output the reports you want. You can put all your bookings in one monolithic file (shudders!) or daisy chain multiple files with special "include" syntax, neatly organized in folders by fiscal year, by bank, or by however you organize your life (Zen moment!).
But I have to say again that the tools in this category are the most complex ones, and they can replicate the basic functionalities of commercial accounting programs. Setting them up or configuring them is relatively easy compared to actually using them. Unfortunately, there is no way around it; eventually, you need to have some understanding of the basic bookkeeping concepts, like the income statement, balance sheet, chart of accounts, or the dreaded "debit and credit".
This is a very simple transaction in Beancount, but the concept is the same in all 3, just some variation in syntax:
2023-01-09 * "You have won second prize in a beauty contest. Collect $10."
Assets:Banks:Monopoly 10.00 USD
Income:Prizes -10.00 USD
I will try to break down this transaction into important parts, and along the way I will try to explain some concepts of accounting because these components are not exclusive to Beancount.
First, every transaction must have a date 2023-01-09
. And then you need to put some description on the transaction so you can remember it next year when you are doing your taxes. Sounds familiar? You have to comment your code...
In the second line, we have the bank account, showing where the money stays. Because we received some money in our bank account (actually, it's precisely 10.00 USD) and since it increased our money in the bank, the amount is positive. The proper term for positive in the accounting world is debit.
The last line has another account, the income account, which basically explains where the money comes from. And a negative amount, that is credit. I don't know exactly why it's called debit and credit, but I believe it is because negative (ergo positive) numbers were not very popular when humans invented the double entry bookkeeping method. Also, it doesn't matter, you just need to know that in every transaction, the total of the lines must be exactly zero. The total of debit amounts has to be equal to the total of credit amounts. Perfectly balanced, as all things should be. Especially the balance sheet.
I am afraid, the rest of the accounting principles you need to learn yourself if you are still interested. I don't have enough space here, we still have to talk about beancount and fava.
Beancount and Fava
First things first, beancount is the name of the accounting program, and fava is the web-based frontend to show reports generated by beancount. You can use beancount alone, it's actually a standalone CLI application, but if you want to see your finances in a web browser, you need both beancount and fava.
Beancount is developed in Python, the stable version is v2. v3 is still under development (since June 2020, ¯\_(ツ)_/¯
). Fava only supports beancount v2 anyway and there is a nice docker image that bundles both of them together. And starting it is as easy as this:
docker run -v $PWD:/bean -p 5000:5000 /-e BEANCOUNT_FILE=/bean/example.bean yegle/fava
Next, you probably know what to do. Head to http://localhost:5000 and you will be greeted by Fava.
/bean/example.bean
is where your transactions resides, and you only need a text editor to edit it. There is even a VS Code extension for auto-completion and syntax error checks. Beancount parses the .bean
file and does its magic, then Fava uses it to prepare a balance sheet, an income statement, and some other reports.
Now, what you are going to put inside that file is a whole other documentation. Actually, you should check it out. You might find it overwhelming, a lot of information is there, and it might seems a little bit disorganized. I advise you to start small. Maybe first start with one bank account and one month. Don't go on a quest in your attic to reconcile your last 10 years of financial records.
Once you figure that out, I will meet you on the other side of the rabbit hole. Because apart from the fava you have many additional tools, like bean-query, the SQL-like query client, bean-price, the tool to fetch current prices of your commodities (stocks), or probably someone made an importer for your bank.
The tasks you can achieve with beancount are endless. As I mentioned, you can monitor your spendings or analyze your revenue streams. You can track the performance of your investment portfolio. It can help you do your taxes. You can keep track of your vacation days or loyalty points. You can upload your documents and link transactions to them. Or daydream about the day you fully pay your mortgage.
What you will not find for beancount is a fancy mobile app or a modern UI, though fava is not that bad. The learning curve can be steep, and typing each transaction manually will be a chore. So you definitely need to figure out an importer and use the VS Code extension.
My main bean file is called "yevmiye.beancount" (which means ledger in Turkish). This file just has a few options and "include" directives, referencing other beanfiles. I create a different folder for each year, and each bank account has a different bean file in these folders. You can use include to daisy-chain your files. Then I have mounted this folder in a code-server container, so I can edit the files on my laptop or with a tablet in a café (No, I don't have a life, thank you very much). All my ledger are pushed to the repository in my Gitea instance.
At the beginning of each month, usually on a Sunday morning, I download my bank accounts in Excel format and "categorize" each transaction, each category is basically a short code for the account for which this transaction should be booked. Then I convert the Excel files to bean syntax with a python script and paste the transactions at the bottom of the bean file for that bank. But there is most likely an importer made for your bank. There are also importers using AI to suggest accounts.
Another Python script checks the current price of stocks and coins I have in my sad portfolio every hour, using the unofficial Yahoo Finance API. And I feel sorry hourly for wasting so much resource on my depressing investments. Then I have another Python script that runs a bean-query and publishes the results as MQTT messages, so I can create a sensor for my abysmal net worth in Home Assistant. Because... why not...