Previously I used Mint to track my finances across all my accounts. When it shut down, my dad moved to Monarch, which inspired me to find a replacement as well.
My main priorities were privacy and control. Though it takes more effort to ledger manually, I’m no longer relying on some corporation that could disappear and take their service with them. Since my finances are congregated in my hands, my financial habits are much more private (well, as private as they can be without going the Monero and cash only route). Also being text based, I get much more control granted by the ability to write scripts that automatically add entries and integrate with my environment.
Biggest downside, which I’m mostly over now that I’m used to it, is that there
isn’t any pretty eyecandy visualizations, like pie charts or line graphs to
generate reports with. There is gnuplot
functionality, but I’ve found it to
be limited (more likely I didn’t spend enough time figuring it out).
hledger
might have more features, but I find it difficult to justify
installing dozens of Haskell dependencies for a single program.
~/ledger
accounts
commodities
prices
transactions.ledger
My accounts
file is used to keep a list of “categories” for my assets,
income, expenses, etc. I have my configuration file set up such that any
account that isn’t explicitly listed in this file will cause an error when
generating ledger reports.
commodities
is similar to accounts
, rather it keeps track of which symbols
are legal in my ledger, to prevent typos like VLVXV when I meant VLXVX. Also
whitelists USD, JPY, and other currencies.
prices
exists to track the value of various symbols. Manually updating this
is a pita so I set up a nightly cron job in tandem with a python script which
queries AlphaVantage’s API for a list of symbols, and appends them to this file
in a Ledger friendly way.
If you choose to use it, dont forget to set the LEDGER_PRICE_DB
environment
variable to the path of your price file. Oh, and the API key is unwisely stored in
a variable. My cron job defines it in the same line:
0 0 * * * LEDGER_PRICE_DB=$HOME/ledger/prices python $HOME/.scripts/update_ledger_prices.py
Lastly, transactions.ledger
is the ledger. I have set up a few cron jobs
to automatically add uncleared transactions for various recurring bills.
Which once I verify/acknowledge them, I’ll change their status to cleared.
printf "\n<date> <payee>\n\t<account>\t x.xx USD\n\t<account> " >> ~/ledger/transactions.ledger
Favorite reports:
To simply show net worth:
$ ledger b Assets Liabilities
Shows a high level overview of Expenses and Income on a month-by-month basis.
$ ledger r Exp Inc --monthly --market --depth 1
Sometimes I’ll append the --effective
flag to get a better idea of how less
frequent paid-up-front bills are distributed over following months. Like
insurance or my mobile plan.
On most reports I’ll use the --market (-V)
flag to translate the current value of
my holdings to USD. For accuracy it’s important to keep an up to date list of
symbol prices and currency exchange rates.
I set up a script in my path named transact
, which opens and sets my cursor
to the bottom of the transactions.ledger
file. After exiting my editor, a
signal is sent to dwmblocks
and/or waybar
to refresh the related custom
ledger status module(s). (Right now I only have one to sum the overall balance
between my all my liability accounts)
#!/bin/sh
nvim + ~/ledger/transactions.ledger
pkill -RTMIN+3 dwmblocks #waybar
A nice discovery I made is that Neovim’s treesitter plugin has support for ledger syntax highlighting.
Read more about ledger here
I reference the manual when I get bored, try to pick up new reporting and organization abilities.