Ledger keeps popping up on my radar, that was the most recent one, so I decided to take a look to see if I could use it to replace Pocketsmith for our family financial fiasco planning. I don't really have any issues with Pocketsmith: It is great, easy to use, requires minimal in-application time and really helps visualise things when going through finances with someone else. I've been using it for almost 5 years. From a purely personal perspective, though, a command line tool would be better since Pocketsmith runs slow on my PIII. However, it isn't the tool that is the problem - I know this because I'm writing this blog post quibbling about saving £3.25 a month, an entirely inconsequential amount in our scheme of things, but that's about all that's left that I can influence.

Installing

The NetBSD package is so out of date it won't work (website addresses have changed) so I looked at installing from source.

I needed the following packages:

  • editline
  • boost
  • gcc49 (Since the system version isn't recent enough)
  • mpfr

I already had cmake installed.

I tried to checkout a stable branch, but the acprep build tool doesn't seem to work with it so I checked out master instead. Within the directory I did the following so the correct version of gcc would be used:

export CXX=/usr/pkg/gcc49/bin/g++
export CC=/usr/pkg/gcc49/bin/gcc

It actually takes some time to build for a command line tool. And uses a lot of memory during build. I was quite surprised.

I had the same cmake INSTALL_RPATH_USE_LINK_PATH issue I had on Taskwarrior where links (dynamic object dependencies) to things in /usr/pkg got stripped on install, but I'd forgotten about this initially. For Taskwarrior I'd put it in one of the CMake files, but I couldn't get that approach to work with Ledger. In the end doing the following, before building, worked:

cmake . -DCMAKE_INSTALL_RPATH_USE_LINK_PATH:BOOL=ON

Using

The main reason I use Pocketsmith is for forecasting. I don't care as much about "budgeting" (analysing where the money went); there is nothing I can do by that point.

Unfortunately forecasting in Ledger is a bit crap. And full of bugs that have been there for years.

I tried using a ~ monthly from <DATE> syntax, but then those transactions were completely ignored so I settled for just using ~ monthly and ~ weekly and letting Ledger decided when they would be applied. However, even using it this way it still seemed to behave in a screwy way with a mix of weekly and monthly periodic transactions. Here's a register report, with a running total on the right:

$ ledger -f transactions.dat --forecast "d<[2015/07/25]" reg ^assets ^liabilities

15-Jun-14    Transfer from savings    Assets:Current                 £250.00    £242.21
                                      Liabilities:Owed to savings    £250.00    £492.21
                                      Assets                        £-250.00    £242.21
15-Jun-14    Transaction1                                            £-61.00    £181.21
15-Jun-14    Transaction2                                            £-59.00    £122.21
15-Jun-14    Transaction3                                             £88.68    £210.89
15-Jun-14    Transaction4                                             £45.00    £255.89
15-Jul-01    Forecast transaction                                   £1251.57    £1507.46    <-- A monthly periodic transaction
15-Jun-21    Forecast transaction                                    £-95.60    £1411.86    <-- A weekly periodic transaction
15-Jun-28    Forecast transaction                                    £-95.60    £1316.26    <-- It's counting down ok
15-Jul-05    Forecast transaction                                    £-95.60    £1220.66    <-- Still ok
15-Jul-12    Forecast transaction                                    £-95.60    £2376.63    <-- What the hell has happened here?!
15-Jul-19    Forecast transaction                                    £-95.60    £2281.03

That just seemed crazy! I figured out, though, that this was because I needed to sort by date, then it worked as expected:

$ ledger -f transactions.dat --sort date --forecast "d<[2015/07/25]" reg ^assets ^liabilities

15-Jun-14    Transfer from savings    Assets:Current                 £250.00     £242.21
                                      Liabilities:Owed to savings    £250.00     £492.21
                                      Assets                        £-250.00     £242.21
15-Jun-14    Transaction1                                            £-61.00     £181.21
15-Jun-14    Transaction2                                            £-59.00     £122.21
15-Jun-14    Transaction3                                             £88.68     £210.89
15-Jun-14    Transaction4                                             £45.00     £255.89
15-Jun-21    Forecast transaction                                    £-95.60     £160.29
15-Jun-28    Forecast transaction                                    £-95.60      £64.69
15-Jul-01    Forecast transaction                                   £1251.57    £1316.26
15-Jul-05    Forecast transaction                                    £-95.60    £1220.66
15-Jul-12    Forecast transaction                                    £-95.60    £1125.06
15-Jul-19    Forecast transaction                                    £-95.60    £1029.46

But I couldn't get the register and the balance report to tie up, with or without sorting:

$ ledger -f transactions.dat --forecast "d<[2015/07/25]" bal ^assets ^liabilities
    £1935.43    Assets
    £2185.43      Current
     £250.00    Liabilities:Owed to savings
--------------------
    £2185.43

I have absolutely no idea how it calculated those values.

With further playing about I found out that you can actually get the from and since syntax to work for periodic transactions, you just need to ensure the effective dates are in the past (before today's date), e.g:

~ Monthly from 2015/06/16
    Expenses:Shopping    £500
    Expenses:Car:Petrol    £120
    Income:Other    £-137.60
    Assets:Current

However, this didn't do what I had hoped: the transactions were still applied at the same date, i.e. monthly transactions on the 1st of the month. This makes it completely useless for mid-month forecasting.

The only way I think I can get Ledger to work for me is to include a months worth of pending transactions at the bottom of the file and comment them out as needed (as the actual transactions occur). This may actually be better than forecast transactions in a way, since I'll have to manually reconcile them. Where as otherwise, if a forecast transaction is actually a couple of days late coming out of the bank, the forecast report could be misleading, and look better than it really is, because Ledger will have automatically stopped applying the forecast transaction as the date will have slipped into the past.

This proposed approach would only really work month to month, not any further in advance, because otherwise I'd have an unmanageable amount of pending transactions; I'm also going to have to manually change the dates each month; Apart from the hassle though, month to month budgeting is fine for my needs. I've checked and this idea works, since not including the --forecast command still takes into account the future dated pending transactions. Also, I get the register and balance reports matching!

So I'm going to have a go at this approach, but keep Pocketsmith running simultaneously until I've decided which to keep using.

I've also had a look at, but haven't installed, hledger and beancount. As far as I can tell they are actually feature limited compared to Ledger from my point of use.


[EDIT: 2015-10-19] Previously I'd written that sudo make install -DCMAKE_INSTALL_RPATH_USE_LINK_PATH had fixed my problems, but having just upgraded to NetBSD 7 and rebuilding Ledger that isn't actually true. I either recalled that incorrectly or things have changed for no apparent reason under NetBSD 7; probably the former.

[EDIT: 2015-10-21] I'm 90% sure (but bear in mind how I recalled something incorrectly just above) that upgrading to NetBSD 7 has somehow broken Unicode in Ledger. When I upgraded NetBSD I did not (and mostly still haven't) upgraded my Userland. So my existing Ledger install started printing <A3> for £. I assumed it might be because NetBSD had upgraded some libraries that Ledger was linked to (although this doesn't make sense in hindsight), but I have tried re-building the release, current and next branches against both utfcpp and building the Boost libraries from source so I could use Boost linked against Icu (I just used the Boost binaries last time which are not linked to Icu). Still no luck. I can't figure it out. So I've given up and I'm quoting my pound signs ("£") in my Ledger files and Ledger has no problem with that. Since most of my transactions are produced automatically this isn't really inconvenient; It only effects pending transactions I'll enter manually.