Automating allocation reports in Ledger.25 Nov 2016
If you own any stocks or funds you probably want to track the allocation, meaning how much money is in stocks and funds respectively. Some fairly well known low key investment strategies rely on balancing this ratio, for instance this one.
In Ledger, allocations can be modelled easily through allocation based accounts and automatic transactions. This is outlined here. If you do this however, you still have to manually update allocations for every fund you own which is a nuisance, especially if you own something like a target retirement investment fund which naturally and purposefully changes its allocation strategy over time.
In a nutshell, we need an automated way of creating records like this:
= expr ( commodity == 'VFIFX' and account =~ /^Assets:/ ) (Allocation:Cash) 0.0178 (Allocation:Stock:US Stock) 0.5383 (Allocation:Stock:Non US Stock) 0.34259999999999996 (Allocation:Bond) 0.0968 (Allocation:Other) 0.0045000000000000005
This would then allow fun queries like
ledger bal Allocation: -X '$'
which roughly yields
200.00$ Allocation 60.00$ Bond 20.00$ Cash 2.00$ Other 118.00$ Stock 38.00$ Non US Stock 80.00$ US Stock
ledger bal Allocation: -X '$' -%
which roughly yields
100.00% Allocation 30.00% Bond 10.00% Cash 1.00% Other 59.00% Stock 19.00% Non US Stock 40.00% US Stock
A reasonable source for asset allocation per fund is Morningstar. There, each fund has a Portfolio page which shows asset allocation. Let’s try to extract that.
First, let’s use Ledger to determine what kind of commodities we might need to figure out allocation for:
Essentially, we use a few XPath expression to find the relevant data in the page and extract the asset allocation. The code ommitted here is a very dumb heuristic to determine allocation when we are not dealing with a fund or when no data is available. We use the category name, which is usually something like “Total Stock Market Fund” or “Total International Bond Market Fund” as a basis for the allocation decision and otherwise just assume it’s a stock for the simple reason that I don’t trade individual bonds.
As usual, the code for this is here.Tweet