Back to catalog

hledger-analysis

Parse hledger journals for dividends, expenses, and budgets.

Category 💰 Wealth
Version v1.0

Hledger Analysis

When to use

  • Joseph asks "how much dividend?", "what were my expenses last month?", "which category was highest?"
  • Monthly/quarterly financial reports
  • Income vs expense tracking
  • Budget vs actual analysis

System location

wiki/wealth/hledger/ — full hledger setup with 50+ files across journals, scripts, import rules, and source files.

Architecture

  • Import: Runs locally on Joseph's Mac (run-pipeline.sh). Downloads CSVs → preprocesses → hledger import → dedup → check.
  • Sync: Journal files sync to server via Dropbox.
  • Analysis: Python scripts on server parse .journal files directly. No hledger binary needed on server.

Key directories

hledger/
├── journals/              ← Transaction data (THE source of truth)
│   ├── main.journal       ← Hub file (includes everything)
│   ├── accounts.journal   ← Chart of accounts (177 lines)
│   ├── balances.journal   ← Opening + reconciled balances
│   ├── 2025/              ← Per-account journals (14 bank accounts + cards + investments)
│   └── 2026/              ← Current year
├── scripts/               ← Python analysis + import scripts
├── import-rules/          ← hledger CSV import rules (per bank)
└── source-files/          ← Raw CSVs + PDFs from bank websites

Accounts of interest

  • Dividends: Income:Dividend:JJU:* (per-stock: ITC, COAL, INFY, ASHLEY, etc.)
  • Income: Income:Consulting:, Income:Interest:, Income:Rent
  • Expenses: Expenses:Home:, Expenses:Car:, Expenses:Travel:, Expenses:Tax:, etc.
  • Transfers: Assets:Bank:Transfers (inter-account moves)

Journal format (for parsing)

2026-04-18 ACH/TVS MOTOR IDIV26/...
    Assets:Bank:ICICI:Demat              6000.00
    Income:Dividend:JJU:TVSMOT        -6000.00
  • Header: YYYY-MM-DD [*!]? description
  • Postings: Account:Path amount (4+ spaces indent)
  • Blank line = transaction separator
  • Comments: lines starting with ;
  • Convention: income = negative amounts, expenses = positive amounts

Parsing rules

1. Transaction header matches ^(\\d{4}-\\d{2}-\\d{2})\\s+([!]?\\s.+)

2. Postings match ^(\\s{4,})([\\w:]+)\\s+(-?[\\d,]+\\.?\\d*)

3. Blank line or another header ends a transaction

4. Skip comment-only lines (starting with ;)

Analysis approach (no hledger on server)

Python scripts parse journal files directly:

  • Filter by account pattern (Income:Dividend:, Expenses:)
  • Filter by date range
  • Group by category/month/stock
  • Aggregate (sum, count, average)

See references/journal-format.md for detailed format spec.

See references/existing-system.md for documentation of all existing scripts and their capabilities.

Pitfalls

1. Don't install hledger on server — Joseph explicitly said not to for now. Parse journals with Python.

2. Hledger convention: Income amounts are negative, expenses are positive. When summing, use abs() for income.

3. Reconciled entries have balance assertions in balances.journal — these are ground truth.

4. Multi-year data: Journals span 2025 + 2026. Always check both year directories.

5. Import is local: The server only has whatever synced via Dropbox. If data looks stale, Joseph needs to run import locally first.

6. Credit card journals are generated by import-cc-2025.py (different format than bank journals) — parser must handle both.

7. Inter-account transfers appear in both account journals — dedup-transfers.py removes duplicates after import.