If you use any of the banks or institutions already supported (e.g. Wise, Monzo, Revolut, Interactive Brokers) you can get advantage of already provided code and a web UI for semi-automated categorization, at least for these accounts.

Process

The idea is to take data from your bank and convert it to a list of Beancount statements automatically or almost automatically.

Now, there are quite a few steps between doing everything manually and a magical cron job that handles updates for you magically. The whole process would need to involve:

  1. Download the data from bank
  2. Parse the data into Beancount format
  3. Add/edit categories, tags, whatever
  4. Deduplicate transactions

This is the part where ready-made financial tools may be appealing as this is what you pay for them to do. For plain text accounting there is no single silver bullet that will solve everything as of yet (not that it’s impossible, maybe it will take a bit of time for a more advanced and maintained instruments to appear).

For now, I opted out to ignore 1) since it’s the part that’s more prone to breaking and it’s not that hard to do manually anyway. As for the other steps, you will get help from provided systems.

Lazy Beancount UI

You will need to download your statements in CSV format from the app or bank website. Don’t start with a full year worth of transactions, usually going through one month is enough for a session. You can import more when you need it or have a particular mood for transaction classification.

Importers config

Put downloaded files in the corresponding folder in data/beancount_import_data.

If you need more custom configuration or more currencies, edit the importers_config.yml file. Keys in the config correspond to the import directories, and any CSV files in the corresponding folder should be picked up. After editing and saving the file, don’t forget to restart Docker container.

Import files

After editing the file head to the Import tab where you will be able to upload files to correct directories (you can also do it manually if you prefer). It also has an embedded beancount-import interface where you will be able to go through the list of all transactions and review categorization – or ignore the transaction.

Beancount-import interface

  • ‘Enter’ to accept and write transaction
  • Shift+Enter’ to modify transaction after accepting it
  • ‘i’ to ignore (move to ignored.bean file that doesn’t get included in the ledger but is considered by beancount-import)
  • ‘a’ to change auto-suggested account (with the help of autocomplete)
  • ’#’ to add/edit tags

Detailed documentation with other shortcuts and options can be found at https://github.com/jbms/beancount-import.

After you go through all the candidates, your ledger will be full with transactions imported directly from your bank. Note that:

  1. You don’t have to make sure the source csv files don’t contain same transactions. They can overlap in any way, the library makes sure the identical data rows are never imported twice.
  2. Feel free to edit resulting bean files to do any ad-hoc categorization, adding tags, adding comments or splitting expense between several accounts.
  3. Sometimes you may need to restart docker container. This system is not completely robust yet. Watch for error logs in Docker console if the interface doesn’t work as expected.

Result

Expenses breakdown should become much more meaningful now (see also Advanced Fava). If before you would have only expenses in the Expenses:Unattributed:* category, that is basically coming from your pad operations, now the expenses will be categorized as you want.

Expenses detailed

Note the difference between Unattributed and Uncategorized, the former means the expense doesn’t appear in transactions at all (it’s like the amount just disappeared from the account), the latter means that the transaction is there but the classifier failed to assign it an appropriate category and you didn’t assign it manually either. Ideally, after you imported all your transactions, Expenses:Unattributed:* for corresponding account should be zero or close to zero. Since no-op pad operations trigger an error, you may need to comment them out in some of the totals/* files.