Purely Functional Personal Finance

Andreas Pauley - @apauley

10 September 2018

Purely Functional Personal Finance

with hledger

https://pauley.org.za/functional-finance-hledger/

Code for these slides: https://github.com/apauley/functional-finance-hledger

What do I want?

  • The full picture
  • Full control
  • Useful info from my data
  • Low maintenance
  • Privacy
  • Open (future proof) file/data formats

The full picture

  • All major financial events
    • buying/selling a house
    • bonuses, shares
  • Multiple currencies/assets
    • Rands, Dollars, Bitcoin, eBucks etc

Full control

  • Classify transactions in a way that makes sense to me
  • Easily improve or change how I classify transactions
  • Time: decide when and how much of my time to spend

Useful info from my data

  • Average expenses over the past n months (budgeting)
  • Net worth over time - hopefully increases every year
  • Expose "hidden" expenses, e.g. taxes
  • Expose "hidden" income, e.g. company benefits
  • Separate tax-related accounts
    • Interest vs Dividends vs Capital Gains vs Income
    • RA's, Tax-free Savings Accounts etc

And don't forget…

  • Low maintenance
  • Privacy
  • Open (future proof) file/data formats

What are the options?

  • Online systems e.g. 22seven, YNAB
  • Your Own Spreadsheet™
  • Traditional Desktop Apps e.g. GnuCash, Quicken
  • Plaintext Accounting software e.g. hledger, ledger, beancount etc

Online Apps: 22seven/YNAB

Pros Cons
Low learning curve No full picture
Auto import some accounts No multi-currency support
Day-to-day view  
Low maintenance Low on Privacy
Pre-created reports No custom reports
Auto-classification Useful classification

Your Own Spreadsheet™

Pros Cons
Full picture High maintenance
Flexible Transaction import
Learning curve Everything is DIY
Built-in graphs Not an accounting tool
Privacy  

GnuCash

Pros Cons
GUI GUI
Full picture High maintenance
Multi-currency GUI-approved currencies
Import statements Manual classification
Reports Black box - hidden internals
Privacy Easy to screw it up
  Learning curve

hledger

Pros Cons
Plain text files Learning curve
Full picture Only for geeks
Multi-currency Some DIY Reports
Import statements  
Rules-based classification  
Maintenance  
Privacy  

A Purely Functional Approach

  • Driven by CSV statements - the input data
  • Classified with rules - the functions
  • Generated plain text journal files - the output

Introducing hledger-makeitso

https://github.com/apauley/hledger-makeitso

  • Inspired by Full-fledged Hledger
  • A CLI program (script?) written in Haskell using mostly Turtle
  • Basically the parts of my automated hledger setup that aren't specific to me

The hledger-makeitso workflow

  • Save an input CSV file to a specific directory
  • Run: hledger-makeitso import
  • Add some classification rules if you want

Example

An input file

2,account_number,'MR JOHN D DEER','FNB TJEKREKENING'
3,,'Staat'
3,'Staatnommer','Vanaf Datum','Tot Datum','Openingsaldo','Afsluitingsaldo','BTW Gehef'
3,55,'28 Desember 2017','28 Januarie 2018',0.01,0.01,-0.01
4,,'Opsomming'
5,,'Transaksies'
5,'Nommer','Datum','Beskrywing1','Beskrywing2','Beskrywing3','Bedrag','Saldo','Opgeloopte Koste'
5,1,'29 Des',"Payment received","Company, Inc",,5000.01,7000.01,
5,2,'01 Jan',"POS Transaction","Grocery Store","My town",-4000.00,3000.01,
6,'END'

Copy it here:

import/mybank/savings/1-in/2018/123456789_2018-01-30.csv

Optional preprocessing

https://github.com/apauley/fnb-csv-demoronizer

"5","'Nommer'","'Datum'","'Beskrywing1'","'Beskrywing2'","'Beskrywing3'","'Bedrag'","'Saldo'","'Opgeloopte Koste'","account2"
"5","1","2017-12-29","Payment received","Company, Inc","","5000.01","7000.01","","income:spouse:taxyear2018:salary:nett"
"5","2","2018-01-01","POS Transaction","Grocery Store","My town","-4000.01","3000.01","",

Your preprocess script should save it here:

import/mybank/savings/2-preprocessed/2018/123456789_2018-01-30.csv

Opening Balances for the account

2017-12-28 Savings Account Opening Balance
    assets:current:spouse:mybank:savings               R2000.00
    equity:opening balances:spouse:mybank:savings

A rules file

skip 1

fields _, code, date, desc1, desc2, desc3, amount, balance, _, account2

currency R
status *

account1 assets:current:spouse:mybank:savings
description %desc1/%desc2/%desc3

if
POS.*Grocery Store.*My town
  account2 expenses:food:groceries

Run hledger-makeitso import

├── import
│   └── mybank
│       ├── mybank.journal
│       └── savings
│           ├── 1-in
│           │   └── 2018
│           │       └── 123456789_2018-01-30.csv
│           ├── 2-preprocessed
│           │   └── 2018
│           │       └── 123456789_2018-01-30.csv
│           ├── 3-journal
│           │   └── 2018
│           │       └── 123456789_2018-01-30.journal
│           ├── fnb-csv-demoronizer
│           ├── mybank-savings.journal
│           ├── mybank-savings.rules
│           ├── opening.journal
│           └── preprocess
└── import-all.journal

The generated journals

$ cat import-all.journal
### Generated by hledger-makeitso - DO NOT EDIT ###

!include import/mybank/mybank.journal
$ cat import/mybank/mybank.journal
### Generated by hledger-makeitso - DO NOT EDIT ###

!include savings/mybank-savings.journal
$ cat import/mybank/savings/mybank-savings.journal
### Generated by hledger-makeitso - DO NOT EDIT ###

!include opening.journal
!include 3-journal/2018/123456789_2018-01-30.journal

The generated journals

$ hledger print assets:current not:equity
$ cat import/mybank/savings/3-journal/2018/123456789_2018-01-30.journal
2017/12/29 * (1) Payment received/Company, Inc/
    assets:current:spouse:mybank:savings  R5000.01 = R7000.01
    income:spouse:taxyear2018:salary:nett R-5000.01

2018/01/01 * (2) POS Transaction/Grocery Store/My town
    assets:current:spouse:mybank:savings  R-4000.00 = R3000.01
    expenses:food:groceries               R4000.00

Some useful data

Monthly Balances with Average

$ hledger balance --pretty-tables --monthly --average \
   --sort-amount --depth 2
Balance changes in 2017/12/01-2018/01/31:

                         ║       Dec        Jan    Average
═════════════════════════╬═════════════════════════════════
 expenses:food           ║         0   R4000.00   R2000.00
 assets:current          ║  R7000.01  R-4000.00   R1500.00
 equity:opening balances ║ R-2000.00          0  R-1000.00
 income:spouse           ║ R-5000.01          0  R-2500.00
─────────────────────────╫─────────────────────────────────
                         ║         0          0          0

Income vs Expenses

$ hledger -f example/import-all.journal incomestatement \
   --pretty-tables --monthly --average --depth 3
Income Statement 2017/12/28-2018/01/01

                           ║      Dec        Jan   Average
═══════════════════════════╬═══════════════════════════════
 Revenues                  ║
───────────────────────────╫───────────────────────────────
 income:spouse:taxyear2018 ║ R5000.01          0  R2500.00
───────────────────────────╫───────────────────────────────
                           ║ R5000.01          0  R2500.00
═══════════════════════════╬═══════════════════════════════
 Expenses                  ║
───────────────────────────╫───────────────────────────────
 expenses:food:groceries   ║        0   R4000.00  R2000.00
───────────────────────────╫───────────────────────────────
                           ║        0   R4000.00  R2000.00
═══════════════════════════╬═══════════════════════════════
 Net:                      ║ R5000.01  R-4000.00   R500.00

Export to Your Own Spreadsheet™

$ hledger print assets:current not:equity -O csv | grep -v assets:current
"txnidx","date","date2","status","code","description","comment","account","amount","commodity","credit","debit","posting-status","posting-comment"
"2","2017/12/29","","*","1","Payment received/Company, Inc/","","income:unknown","-5000.01","R","5000.01","","",""
"3","2018/01/01","","*","2","POS Transaction/Grocery Store/My town","","expenses:food:groceries","4000.00","R","","4000.00","",""

hledger-export-to-spreadsheet.png

Where to Learn More

http://hledger.org/

https://plaintextaccounting.org/

https://github.com/adept/full-fledged-hledger/wiki

https://github.com/apauley/hledger-makeitso

Questions?