17 June 2015
When I started my first full time job in 2007 I started putting away a little bit of my paycheck every two weeks into savings. For the past two years I haven't been doing that manually. Instead, I've been using Ledger's fantastic automated transactions to put money away without having to think about it, both for long term goals and envelope budgeting.
Automated saving transactions have been great, except that they never really captured the whole picture, nor did they fit a few constraints I wanted:
- When a fund is below a minimum threshold it should get priority
- When a fund is above a maximum it should not receive any more savings
- I don't want to save any more than I actually have available in a given month
For example, I keep an emergency fund that I keep at about $15k. If it falls below, say, $13k, I want to boost it up as fast as possible. But, if I only have $10 left at the end of the month I don't want to try to save more than that.
Algorithms
Ledger's automated transactions can't reach that kind of flexibility because they don't have access to arbitrary account balances (at least as far as I can tell). Also, because they're evaluated at parse time, the first 300 lines of my ledger file are automated transaction rules.
Instead of using automated transactions, I wrote a little program that generates a transaction to be pasted into my ledger. It takes the three constraints above and turns the cash left over at the end of the month into savings without me having to put numbers into a spreadsheet and manually construct the Ledger transaction.
The algorithm happens in two stages and acts on a set of rules, something like this:
RULES = [
{ 'Emergency' => { min: 13000, max: 15000, weight: 10 } },
{ 'Medical' => { min: 1500, max: 4000, weight: 8 } },
{ 'House' => { min: 3000, max: 15000, weight: 8 } },
{ 'Furniture' => { min: 200, max: 4000, weight: 4 } },
{ 'Travel' => { min: 2000, max: 20000, weight: 4 } },
]
It also depends on having a few numbers available, namely the balance of each fund in the set of rules as well as how much excess cash there was at the end of the month.
The algorithm then takes two passes over the rules.
Sum up the weights in all of the rules. If the account balance is greater than or equal to the max, set the weight to zero. If it's below the min, multiply the weight by 4. Keep track of the total weight in the set and the calculated weight for each rule.
For each rule, calculate the percentage "share" by dividing the account weight by the total weight. Then calculate the amount of this share by multiplying it by the remaining income, up to the max for that fund. Subtract that amount from the remaining income, subtract that rule's weight from the total weight, and continue down the rules until you're out of money.
Each rule is evaluated in terms of two shrinking pies: the total weight and the remaining income. When no funds hit their max value this is strictly equivalent to a straight percentage savings, but elegantly deals with both the min and max situations.
Here's what that looks like in code:
account_weights = {}
total_weight = 0
RULES.each do |rule|
account = rule.keys.first
rules = rule.values.first
weight = rules[:weight]
if (fund_balances[account] || 0) < rules[:min]
weight = weight * 4
elsif fund_balances[account] >= rules[:max]
weight = 0
end
total_weight += weight
account_weights[account] = weight
end
xtns = {}
RULES.each do |rule|
account = rule.keys.first
rules = rule.values.first
weight = account_weights[account]
balance = fund_balances[account] || 0
share = weight.to_f / total_weight.to_f
deposit_amount = [
remaining_income * share,
rules[:max] - balance
].min
next if deposit_amount.round == 0
total_weight -= weight
remaining_income -= deposit_amount
xtns[account] = deposit_amount
end
This algorithm has some great properties:
- The priority of a fund is determined by it's placement in the rules. Earlier funds get funded before later funds.
- The amount a fund gets is determined by it's weight. Higher weight gets a bigger share.
- Funds below their minimum get plumped up with the weight multiplier, while full funds automatically drop out.
The only drawback is that I have to manually run this script every month, but I feel like that's a small price to pay for the flexibility this gives me. If you're interested in the gory details of the script I put the whole thing in a gist. I'd love to hear your thoughts, even if you just want to tell me I'm crazy.
Tagged:
Personal Finance
Ledger
Read More
8 April 2015
Note: you can find much more information about ledger on ledger-cli.org, including links to official documentation and other implementations. Also, check out my intro to accounting with Ledger.
A few years ago I heard about YNAB, or You Need A Budget. YNAB is a set of rules and associated software that help people to dig themselves out of financial holes and prosper with a budget. The rules are:
- Give Every Dollar a Job
- Save for a Rainy Day
- Roll With the Punches
- Live on Last Month's Income
YNAB embraces both traditional budgeting, where you have a fixed amount of money every month for a category, as well as "envelope budgeting", where you put a fixed amount every month into a category, but if you don't spend all of that it rolls to the next month.
In this blog post I'm going to talk about how to smoothly implement envelope budgeting in Ledger land.
Envelope Budgeting: A Primer
Envelope budgeting is a pretty simple concept. When you receive a paycheck, you separate out a certain amount of money for each category and put it in an envelope. When the money in the envelope is gone, you can't spend any more for that category. Some financial systems actually have you draw out your entire paycheck in cash and put it into physical envelopes, but we're not going to go that far.
Chart of Accounts
If you've ever taken an accounting class you're probably familiar with the concept of a "chart of accounts". In an accounting system, your accounts make a tree, starting from five root accounts:
- Assets
- Liabilities
- Income
- Expenses
- Equity
For example, if you have a checking account, that's an asset, like this: Assets:Checking
. A credit card would be a liability: Liabilities:Credit Card
. Your paycheck would be income: Income:Salary
, and getting groceries would be an expense: Expenses:Food:Groceries
. Equity is out of scope for this discussion, but in a personal finance system it's typically used when you're declaring opening balances in accounts.
Parallel Accounts
The best way to implement envelope budgeting in Ledger is using a parallel chart of accounts. That is to say, a set of accounts that's outside of your normal real-money assets, income, expenses, or liabilities. I've chosen to use Assets:Funds
and Liabilities:Funds
("fund" as in "slush fund") in the examples that follow, but you can use whatever you want as long as it doesn't mix with your real money accounts.
Let's say our water bill comes every other month and averages $100. In a traditional monthly budgeting system this would be hard to account for, since some months will be zero and some will have a charge. With our parallel accounts, though, this is easy:
2015/04/02 * Salary
Assets:Checking $1,000.00
Income:Salary
2015/04/02 * Water Bill Accrual
Assets:Funds:Water $50.00
Liabilities:Funds:Water
2015/05/02 * Salary
Assets:Checking $1,000.00
Income:Salary
2015/05/02 * Water Bill Accrual
Assets:Funds:Water $50.00
Liabilities:Funds:Water
At the beginning of April and May, we receive our salary deposit and set aside $50 each time for your water bill. Notice how, in the accrual account, we're depositing into our Assets:Funds:Water
account and balancing it out from a companion liability. This reflects the fact that in double entry accounting every transaction has to balance, and dedicated balancing liabilities make things easier later on. Here are our balances:
$2,100.00 Assets
$2,000.00 Checking
$100.00 Funds:Water
$-2,000.00 Income:Salary
$-100.00 Liabilities:Funds:Water
--------------------
0
Now let's look at what happens when our water bill comes due:
2015/05/03 * Water Bill
Expenses:Water $95.00
Assets:Checking $-95.00
Liabilities:Funds:Water $95.00
Assets:Funds:Water $-95.00
Notice how we pull $95 out of our checking account and also pull $95 out of our Liabilities:Funds:Water
account.
Here's what the balances look like now:
$1,910.00 Assets
$1,905.00 Checking
$5.00 Funds:Water
$95.00 Expenses:Water
$-2,000.00 Income:Salary
$-5.00 Liabilities:Funds:Water
--------------------
0
$95 went from the checking account into the water expense and the water fund still has $5 in it.
Automated Envelopes
This system would be a pain in the butt if we had to manually track it for every transaction. Thankfully, Ledger has us covered with automated transactions.
An automated transaction looks a lot like a normal transaction, except it starts with an =
and has an expression instead of a payee and date. Let's see what our water accrual rule looks like:
= /Income:Salary/
* Assets:Funds:Water $50.00
* Liabilities:Funds:Water $-50.00
In this example the expression is a regular expression surrounded by /
s. /Income:Salary/
will match any posting with that as the account name.
After the expression we have two lines. They start with a *
to indicate that they're cleared transactions. Next is the account name and an amount, just like in a normal ledger transaction.
Now, let's set up a matching rule for spending out of the envelope:
= /Expenses:Water/
* Liabilities:Funds:Water 1.0
* Assets:Funds:Water -1.0
This one is very similar to the first, except for those amounts. Notice how they don't have a commodity attached to them? In automated transactions, ledger will treat an amount without a commodity as a percentage, where 1.0 = 100%. This rule means that we want to match every water expense and pull 100% of it out of our water envelope.
Putting it all together, here's what the automatic version looks like:
= /Income:Salary/
* Assets:Funds:Water $50.00
* Liabilities:Funds:Water $-50.00
= /Expenses:Water/
* Liabilities:Funds:Water 1.0
* Assets:Funds:Water -1.0
2015/04/02 * Salary
Assets:Checking $1,000.00
Income:Salary
2015/05/02 * Salary
Assets:Checking $1,000.00
Income:Salary
2015/05/03 * Water Bill
Expenses:Water $95.00
Assets:Checking $-95.00
Here's the resulting register report:
15-Apr-02 Salary Assets:Checking $1,000.00 $1,000.00
Income:Salary $-1,000.00 0
Assets:Funds:Water $50.00 $50.00
Liabilities:Funds:Water $-50.00 0
15-May-02 Salary Assets:Checking $1,000.00 $1,000.00
Income:Salary $-1,000.00 0
Assets:Funds:Water $50.00 $50.00
Liabilities:Funds:Water $-50.00 0
15-May-03 Water Bill Expenses:Water $95.00 $95.00
Assets:Checking $-95.00 0
Liabilities:Funds:Water $95.00 $95.00
Assets:Funds:Water $-95.00 0
For every paycheck, $50 went into our fund. When we paid the water bill, $95 came out of the fund. To set this up for more envelopes, just create a corresponding pair of rules for each one.
One last thing. What if we want to change how much we're setting aside in the water envelope? Let's say our rates go up and we now need to save $55 from each paycheck instead of $50. Here's how we do that:
= /Income:Salary/ and expr date >= [2015/04/01] && date < [2015/06/01]
* Assets:Funds:Water $50.00
* Liabilities:Funds:Water $-50.00
= /Income:Salary/ and expr date >= [2015/06/01]
* Assets:Funds:Water $55.00
* Liabilities:Funds:Water $-55.00
We can't just delete the old rule because then the transactions from before would be off. Instead, we add date expressions to our rules. Ledger's expression grammar is pretty complicated and not very well documented, but this should be sufficient for the rules you'll be writing for automatic envelopes. Ledger's manual has more documentation on automatic transactions.
I put the examples in this gist if you'd like to play with them. You'll need Ledger 3 installed.
Tagged:
Personal Finance
Ledger
Read More
1 January 2012
Note: you can find much more information about ledger on ledger-cli.org, including links to official documentation and other implementations
For the last five years I've kept my personal finances in order using the ledger system, a sophisticated command line program that consumes a lightly formatted text file. It's helped me repay debts and get everything in order, helping me financially absorb an injury last month that would have been extremely detrimental just a few years prior.
The stock ledger program is exclusively command-line oriented. For quick checks and grep
ing over output, this is fine. For some time, though, I've wanted a more graphical, more robust way of looking at my finances. I've also wanted a more familiar query language, since version 2.0's queries were someone limited and version 3.0's query syntax is not very well documented yet. Last year I wrote a simple system that pushed monthly reports out to static HTML files, which got me part of the way there but I really wanted something more flexible. Something where I can just write an arbitrary query and have the output dumped to HTML.
Thus, I present Ledger Web. In Ledger Web, your ledger is kept in a text file, just the same as always, reports are ERB files, and queries are SQL. Ledger Web watches your ledger file and whenever it changes dumps it into a PostgreSQL database table. It's also quite customizable, letting you set hooks both before and after row insertion and before and after ledger file load.
Tagged:
Personal Finance
Ledger
Projects
Ruby
Read More
18 December 2011
Note: you can find much more information about ledger on ledger-cli.org, including links to official documentation and other implementations
I've been using Ledger for almost five years now to keep track of my personal finances. For three of those years I've lived with a roommate of one form or another. Part of living with a roommate is splitting up bills. Some people decide to do this by dividing the bills up between roommates. For example, Pete pays the electric and gas bills and Andrew pays the water and the cable. Other roommates decide to nominate one person to have all of the bills in their name and post the amounts due every month for everyone to see. This is what my girlfriend and have been doing and it's been working great. All of the bills are in my name and I give her a summary every month and she hands me a check. Easy peasy.
Of course, being a complete and utter nerd means that I have to make this more complicated than it needs to be in the name of reducing the amount of work I have to do.
Tagged:
Personal Finance
Ledger
Read More
4 August 2011
Note: you can find much more information about ledger on ledger-cli.org, including links to official documentation and other implementations
Recently my girlfriend and I visited the wonderful city of Vancouver, Canada. While out of country we tend to use my Schwab Investor Checking account because it carries no fees whatsoever, including currency conversions, and it refunds all ATM fees. Last year when we went to Ireland we just kept all of the receipts and figured it out when we got back, which was excrutiatingly painful. Lost receipts, invisible cash transactions, ugh. It hurts to even think about it. This year, I decided to cobble together a simple system so we could track on the fly. Read on to see how it came together.
Tagged:
Personal Finance
Ledger
Read More
23 May 2010
Note: you can find much more information about ledger on ledger-cli.org, including links to official documentation and other implementations
About three years ago I was in some serious financial straits. I had just started my first job out of college that I had moved across the country for and had to bootstrap almost my whole life. This meant buying furniture, buying a car, outfitting a kitchen, etc. Every two weeks I would get a salary deposit, and within two weeks it would be almost completely gone from my checking account. I actually bounced a rent check or two in there. After the second time that happened I vowed it wouldn't happen again and started keeping track of every penny that I spent using a program called ledger. This was, in hindsight, exactly what I needed to get myself back on track. Actually seeing money moving in and out of my accounts forced me to modify my behavior. At the time, Mint wasn't around, but I don't think it would have helped nearly as much. Forcing myself to actually type out the transactions was the key to changing behavior.
Ledger is almost the most boring, austere accounting program you could think of. There's no pretty graphs, no online interaction, no GUI of any sort. It's basically a command-line driven calculator with a lot of specializations that make it ideal for tracking finances, which is what makes it so ideal for someone who spends a lot of time inside a text editor. It's very easy to script around and it has a very rich query language that lets you get at the data that you want with a minimum of fuss. It's very much the inspiration for Calorific.
Tagged:
Personal Finance
Ledger
_evergreen
Read More