Budgeting with ledger-cli
Sunday, Mar 21, 2021
Tags: project, personalfinance, ledger, ledger cli, budgeting
In my Personal Finance Philosophy post, I describe the importance of budgeting and acknowledge that it can be time consuming to do properly. Since I’m a software engineer by trade, I looked for software to help me with the job. Initially, that was practicing double-entry accounting for all my personal finances using GnuCash, an open-source version of Quicken (with less features). It allowed me to understand the workflows, but the integrated expense matcher is terrible and I wanted something better.
I found the
ledger-cli tool which is double-entry accounting software that uses a simple text file as your database. This allows you to use version control (
git) to maintain/version it and write simple scripts to update and modify it (in addition to the already powerful CLI).
My new workflow for managing my budget looks like this:
- Monthly, download CSV exports of transactions from my credit card and bank accounts.
- Use JCF to match the transactions then convert them to a
- Merge each ledger file into my master ledger.
- Check diffs using Git and commit the results if everything looks good.
- Generate an expenses CSV and import it into a Google Sheet where I use a pivot table to break down the expenses in to budget categories.
Sound interesting? Set it up for yourself.
Download transaction CSVs
Monthly, I log in to my bank and credit card accounts and download all the transactions that occurred since the last time I balanced the account with my ledger. It could be automated even more using something like Plaid, but I’m a bit security paranoid so I still do it myself. To start, I invoke ledger to find out the date of the last transaction I have recorded for the account:
# "Account Name" here means plain substring matching from account names # in your master ledger. It could be "Assets" to get all assets or "1234" # to get transactions for Assets:Current Assets:Checking 1234 ~/Development/ledger-scripts$ bash register.sh "Account Name" ... prints most recent transactions
I download CSVs for all transactions that aren’t already in the register (based off date). If I’m balancing a brand new account I just start with 30/60 days. Next, I match them using JCF to expense accounts.
Match transactions and convert to ledger format
See JCF documentation page for Matching
Merge the new ledgers
See JCF documentation page for Merging
Use git to maintain my databases
See JCF documentation page for Committing an update
Use a spreadsheet with pivot table
See JCF documentation page for Expense Reports