Manage Joseph's double-entry bookkeeping via hledger. Located at wiki/wealth/hledger/. hledger 1.52.4 is installed at ~/bin/hledger.
source-files/ and wants it imported~/bin/hledger (v1.52.4)wiki/wealth/hledger/source-files/wiki/wealth/hledger/import-rules/wiki/wealth/hledger/
├── main.journal ← entry point
├── accounts.journal ← chart of accounts
├── balances.journal ← opening/reconciled balances
├── journals/
│ ├── 2025/ ← per-account journals
│ └── 2026/ ← per-account journals
├── import-rules/ ← hledger CSV import rules
├── scripts/ ← preprocessing + import scripts
└── source-files/ ← CSV/XLS from bank portals
└── invest/ ← investment CSVs (ICICI, Zerodha)
├── done/ ← imported files
├── fund-codes.csv ← Zerodha MF short code mapping
├── convert-zerodha-stocks.py
├── convert-zerodha-mf.py
├── apply-zerodha-mf.py
└── sync-holdings.py
cd wiki/wealth/hledger
~/bin/hledger -f journals/2026/<account>.journal \
import source-files/<file>.csv \
--rules-file import-rules/<account>.rules
~/bin/hledger -f journals/main.journal check
~/bin/hledger -f journals/main.journal bal --depth 2
~/bin/hledger -f journals/main.journal bal Expenses:Travel --monthly
~/bin/hledger -f journals/main.journal print desc:"Singapore"
See references/investment-import.md for the full workflow.
python3 wiki/wealth/hledger/source-files/invest/sync-holdings.py
Or dry-run:
python3 wiki/wealth/hledger/source-files/invest/sync-holdings.py --dry-run
1. Place CSV in source-files/
2. Detect format — read first line:
S No.,Value Date,... → ICICI 8-col → run scripts/preprocess-icici-8col.pyS.N.,Tran. Id,... → ICICI Current → run scripts/strip-commas.pyTran Date,CHQNO,... → Axis → use as-is3. Preprocess if needed (step 2)
4. Import with hledger import command (above)
5. Check with hledger check
6. If check fails: report error to user, do NOT auto-fix
Completion criteria: hledger check exits 0 with no output.
Zerodha MF CSVs use commodity tracking (quantity + cost basis), not flat amounts.
Location: source-files/invest/fund-codes.csv
Mapping: short_code → full_name → isin. When importing a new fund:
1. Add row to fund-codes.csv
2. The converter script uses this for commodity naming
Current codes:
PPFCF-DP — Parag Parikh Flexi Cap Fund - Direct PlanPPFCF-DPG — Parag Parikh Flexi Cap Fund - Direct Plan Growth (same ISIN as above)PP-LCF — Parag Parikh Large Cap FundMOMF-DG — Motilal Oswal Midcap Fund - Direct GrowthAX-LF-DG — Axis Liquid Fund - Direct GrowthIISCF-DG — Invesco India Small Cap Fund - Direct GrowthPPAF-DPG — Parag Parikh Arbitrage Fund - Direct Plan Growthcd wiki/wealth/hledger
1. Convert CSVs to staging (dry-run)
python3 source-files/invest/convert-zerodha-mf.py
2. Review staging files in source-files/invest/to-import/zerodha/staging/
3. Apply to journals
python3 source-files/invest/apply-zerodha-mf.py
4. Verify
~/bin/hledger -f journals/main.journal check
Per-fund sub-accounts: Assets:Invest:MFs:Zerodha:{Person}:{FundCode}
Persons: Jerry, Josh, JJU, Rani
Bank accounts: Assets:Bank:ICICI:{Person} (all ICICI)
1. Max 3 import attempts per session. If the 3rd attempt fails, STOP and give a diagnostic report.
2. Never auto-fix import rules in a loop. If import fails:
3. Use the script (scripts/hledger-import.sh) for automated imports — it has built-in max-3 guard.
4. Separate deterministic from interpretive:
5. One change per round-trip. Make one rule fix, Joseph runs the script, we see the result. Never batch multiple rule changes.
Rules follow hledger v1.52 last-match-wins convention:
account2 expenses:unknown)if ZERODHA BROKING → Income:Invest:Gains)common.rules is included by each bank-specific rules fileinclude common.rules.
Assets:Invest:Stocks:ICICIDirect:TICKERjournals/YYYY/icici-stocks.journalsource-files/invest/convert-icici-stocks.pyAssets:Invest:Stocks:Zerodha:PERSON:TICKERjournals/2026/zerodha-stocks.journalsource-files/invest/convert-zerodha-stocks.pyAssets:Invest:MFs:Zerodha:PERSON:FUNDCODEjournals/YYYY/investments.journalsource-files/invest/convert-zerodha-mf.pysource-files/invest/fund-codes.csvAssets:Invest:MFs:ICICIDirect:JJUjournals/YYYY/investments.journalhledger check fails, the journal has a balance mismatch. Don't ignore it."MON100"include lines for files that don't exist yet. A previous session added ICICI Direct MF includes to 2026.journal pointing to source-files/invest/to-import/icici-direct/ — the directory was never created, blocking hledger-web. Only add includes after the target file is in place.After any import:
1. hledger check passes (exit 0, no output)
2. hledger bal --depth 2 shows expected totals
3. No new expenses:unknown entries (grep journals for it)
After investment imports:
1. Spot-check 3 stocks: hledger bal Assets:Invest:Stocks:ICICIDirect:TICKER
2. Compare with holdings.csv: python3 source-files/invest/sync-holdings.py --dry-run
3. Verify no duplicates across brokers