Ledger Filing Hierarchy
How should you structure the hierarchy of your account tree? Here are some examples, which ones would be better?
Example 1:
Assets:Brazil:Banks:ABCBank:Savings
Assets:Banks:Brazil:ABCBank:Savings
Example 2:
Income:Investments:BTrade:Taxable:Dividends:ORNG
Income:Investments:Taxable:BTrade:Dividends:ORNG
Income:Investments:Taxable:BTrade:ORNG:Dividends
Income:Investments:Taxable:Dividends:BTrade:ORNG
All the above are completely valid hierarchies. Beancount lets you slice and dice your transactions any way you want them. So which one do you pick? If you are asking yourself this question, the answer will become intuitively obvious to you as you go about setting up and using Beancount regularly. In the latter example above, I personally use:
Income:Investments:Taxable:Dividends:BTrade:ORNG
# and also:
Income:Investments:Taxable:Capital-Gains:Short:BTrade:ORNG
Income:Investments:Taxable:Capital-Gains:Long:BTrade:ORNG
This is because my most frequently asked questions around these accounts are:
- What is my total investment income (this year/quarter/month etc.)?
- What is the income in my taxable account?
- What is my taxable dividend income vs. taxable income from short and long term capital gains?
And I rarely ask the question “What are all the different types of income from ORNG
?”
The structure above reflects this. I can browse these accounts on fava and get answers
to my questions readily but just glancing at the account trees and summations for the
questions above.
Which one is going to work best for you? This is where your mileage may vary. The great news is, account structure is trivial to change: it is a simple global text replacement of your source files. So I’d recommend not worrying about it, and going with any reasonable structure until it’s intuitively obvious as to what works best for you later on. Simply write a small script to rename your accounts dependably, so you can play around an experiment to your heart’s content as you go along. My script is below. Note that:
- I user per-account files (covered below), which means files need to be renamed
- the replacement changes my importer configs as well, meaning future imports will get filed correctly
- I also use Beancount’s documents feature, which this script handles as well
- if these are not needed, a simple
sed -i 's/Assets:Brokerage:ORNG/Assets:ORNG:Brokerage/' ledger.beancount
would suffice - backup your source file before running any of this!. My ledger files are under revision control (git)
#!/bin/zsh
if [ [ $# -lt 2 ] ] ; then # Remove space between brackets
echo 'Missing arguments. Call like so: rename-account.sh Assets:Old:Name Assets:New:Name'
exit 0
fi
echo "Files touched:"
echo "--------------"
for i in **/*.bc ingest/my.import ; do
if grep -q $1 $i ; then
echo $i
sed -i "s/$1/$2/" $i
fi
done
# Move files/directories
old_filename=source/${1:gs/:/./}.bc
new_filename=source/${2:gs/:/./}.bc
old_docdir=documents/${1:gs/:/\//}
new_docdir=documents/${2:gs/:/\//}
echo ""
if [ -e "$old_filename" ] ; then
echo "Moving source files:"
echo "--------------------"
mv -v $old_filename $new_filename
# change include in main file include
for i in ${BEAN_ROOT}/*.bc ; do
sed -i "s#$old_filename#$new_filename#" $i
done
else
echo "Could not find files to move: $old_filename"
fi
# untested
if [ -e "$old_docdir" ] ; then
echo "Moving document dir:"
echo "--------------------"
mkdir -pv $new_docdir
mv -v $old_docdir/* $new_docdir
mv -v $old_docdir/.* $new_docdir
find documents -type d -empty -delete -print
else
echo "No documents dir to move: $old_docdir"
fi
rm -fv ${BEAN_ROOT}/.main-accounts.bc.picklecache