Open-source

Ledger — Australian personal finance ETL and ATO tax dashboard

2 min read Isaac Rowntree

Zack Design has published ledger — a terminal-first personal finance tool that ingests bank statements from multiple Australian banks, categorises transactions with regex-based rules, and renders an ATO-ready tax return view plus a net worth dashboard. Local-first, SQLite under the hood, no cloud dependency.

The itch

Every mid-year I rebuild the same Excel spreadsheet: paste in ING transactions, paste in PayPal, paste in the Bankwest credit card, then hand-categorise everything, then try to remember which expense was for which business, then double-count a $200 transaction that appeared on both the credit card and the bank account it was paid from. Then I hand it to my accountant and we do it all over again. Ledger is the version I should have built five years ago.

Sources supported today

Source Formats Parser
ING Australia PDF statements, CSV export etl/parsers/ing_pdf.py, ing_csv.py
PayPal CSV activity download etl/parsers/paypal_csv.py
Bankwest PDF eStatements, CSV etl/parsers/bankwest_pdf.py, bankwest_csv.py
HSBC PDF statements etl/parsers/hsbc_pdf.py
Coles Mastercard PDF statements etl/parsers/coles_pdf.py
Amex CSV download etl/parsers/amex_csv.py

Drop a statement into staging/<source>/, run ledger ingest, and the right parser picks it up. PDF parsing is per-bank because every Australian bank has a different statement layout and none of them offer a clean machine-readable export.

What it does

  • Multi-source ingestion. The above parsers, with dedup rules to prevent double-counting when a transaction appears on both a bank account and a credit card.
  • Auto-categorisation. Regex-based merchant rules assign categories automatically and learn from manual overrides.
  • Business splits. A percentage of any expense can be allocated to a business — essential for anyone running a sole-trader side or a company with home-office overlap.
  • ATO tax return view. Output structured to match the sections of an Australian individual tax return: salary, rental schedule, business schedule, deductions.
  • Financial year view. Outgoing / incoming / rental / work-trip sub-tabs replacing the Excel sheet I had been rebuilding by hand every year.
  • Net worth dashboard. Accounts, credit cards, property, vehicles — balances pulled from the same statements.
  • Tags. Orthogonal to categories. A transaction can be in category “Travel” and tagged flight, biz-hosting, rental-income for finer reporting without having to invent a deeper category tree.

Why local-first

Because my financial data is mine. No cloud dependency, no third-party aggregator pulling read-only access to my bank accounts, no “we are deprecating the Xero integration” email six months from now. SQLite sits in a folder, the dashboard runs on localhost, and if I want to back it all up I copy a single file.

Quick start

git clone https://github.com/isaacrowntree/ledger.git
cd ledger
python3 -m venv .venv && source .venv/bin/activate
pip install -e .

cp config/accounts.yaml.example config/accounts.yaml
cp config/categories.yaml.example config/categories.yaml
cp config/tax.yaml.example config/tax.yaml

ledger init
mkdir -p staging/ing staging/paypal
# Drop PDFs/CSVs into those folders
ledger ingest
python -m api
# Open http://localhost:5050

Who it is for

Anyone in Australia with more than one bank account, a side business or two, and an accountant who currently gets a hand-assembled spreadsheet every July. Source on GitHub.