Search...Search plugins and themes...
⌘K
Sign in
  • Get started
  • Download
  • Pricing
  • Enterprise
  • Account
  • Obsidian
  • Overview
  • Sync
  • Publish
  • Canvas
  • Mobile
  • Web Clipper
  • CLI
  • Learn
  • Help
  • Developers
  • Changelog
  • About
  • Roadmap
  • Blog
  • Resources
  • System status
  • License overview
  • Terms of service
  • Privacy policy
  • Security
  • Community
  • Plugins
  • Themes
  • Discord
  • Forum / 中文论坛
  • Merch store
  • Brand guidelines
Follow us
DiscordTwitterBlueskyThreadsMastodonYouTubeGitHub
© 2026 Obsidian

Finance Tracker

AJAJ973 downloads

Log spending as tags in your daily notes, then turn them into pace-aware budget, holiday, and savings dashboards. Capture via Apple Shortcuts or a quick-add modal.

Add to Obsidian
  • Overview
  • Scorecard
  • Updates12

Log spending as tags in your daily notes. Get budgets, trips, savings goals and forecasts back.

Your markdown notes stay the source of truth. There is no database and no sync — uninstall the plugin tomorrow and you still have every transaction, in plain text, in notes you can grep, link and edit by hand.

The recurring payments block: cost per month and per year, upcoming bills with due dates, and one filled Log now on the bill that is actually due

## Finance
- [ ] #log/spending 16.20
    - $12.00 #log/spending/food/restaurants
        - Nobu
    - $4.20 #log/spending/food/snacks

That is the whole data format. Everything below is built from it.

  • Runs on desktop and mobile (Obsidian 1.0+).

  • Network use is opt-in and named. Three features can reach the internet, and none of them does until you ask:

    • GitHub gist capture talks to GitHub, using your own gist and token.
    • Share prices, if you choose a price source other than typing them in: a Google Sheet you publish, or Yahoo Finance's unofficial price feed (whose requests identify as a web browser, since Yahoo refuses anything else). Only the tickers you hold or watch are sent, and only when the portfolio or the hub's Today tab is opened, or you refresh.
    • Trip exchange rates, only when you press Fetch current rate: one request to Frankfurter for the European Central Bank's reference rate between the two currencies.

    No telemetry, no bank connections, nothing phoning home.

  • MIT licensed — see LICENSE.

  • Recent changes: CHANGELOG.md.

Support the project: Buy Me a Coffee

Contents

  • First-time setup — the wizard, and what it creates
  • The finance hub — Today, Inbox, Budgets, Bills, Goals & trips, Portfolio and Reviews in one view
  • How logging works — the tag format, and six ways to capture
  • Tag language — spending, income, balances, trips, splits
  • Categorising — the inbox, suggestions, merchant rules, renaming a category
  • Budgets — pace-aware limits in a markdown table
  • Bills · Runway — one note per bill, and whether your account covers the next month
  • Goals and trips — sinking funds, prompts, trip mode, exchange rates, archiving
  • Dashboards · Reviews — live sections, and frozen weekly to yearly snapshots
  • Accounts & portfolio — balances, shares, dividends
  • Split expenses · Forecast · Query block
  • Daily budget sidebar · Reconciling against the bank
  • Commands · Settings · Limitations · Development

First-time setup (empty vault)

On a fresh install the setup wizard opens automatically (or run the Set up finance notes command / the button at the top of settings any time — it never overwrites existing notes). It asks where your daily notes live, where finance notes should be stored, your currency, and what to name the recurring payments note (changeable later in settings) — then creates the starter notes from templates embedded in the plugin:

First-time setup wizard: folders, currency, recurring note name, and starter notes to create

  • 💸 Budgets.md — the budget table
  • 📊 Finance Dashboard.md — weekly/monthly dashboards, net worth, forecast, a sample query
  • 🔁 Recurring Payments.md — the bill management page
  • 🎯 Goals.md — the goals overview with one-tap contributions

The manual path, if you prefer:

  1. Install & enable. Copy this plugin to .obsidian/plugins/finance-tracker/, then Settings → Community plugins → enable Finance Tracker. (On mobile, turn on community plugins first.)

  2. Set two things in the plugin's settings tab (Settings → Finance Tracker → Capture):

    • Default currency (e.g. AUD, USD).
    • Daily notes folder — point it at where you keep daily notes. Default is Journal/Periodics/1. Daily; the plugin routes captures to <folder>/YYYY-MM-DD.md (or <folder>/YYYY/MM/YYYY-MM-DD.md if you already use that structure).

    Settings tab: Capture — a status line reading 'Reading 684 entries across 132 notes', the currency and capture toggles, and note-format fields folded into Advanced

  3. Open the hub. Click the wallet ribbon icon (or run Open finance hub); the coin icon opens the smaller Daily budget sidebar. This creates, on first run:

    • Utility/Budgets/💸 Budgets.md — a starter budget table you can edit.
    • Utility/Finance/Inbox/ — the capture folder Shortcuts write to.
  4. Log your first transaction. Run command Quick add transaction, type 12 coffee snacks, press Enter. Today's note is created with a ## Finance section and the entry; the panel and status bar update.

  5. Set your budgets. Open 💸 Budgets.md and edit the table rows to your own categories, limits and periods. Keep an all row for the overall bar + Left/Day.

  6. Add a dashboard (optional). Put a ```finance-dashboard block (see Dashboards) in any note for charts and pace bars.

  7. Phone capture (optional but the point). Pick the method that matches your sync (see How logging works): on Obsidian Sync, use a Shortcut that opens obsidian://finance-capture?… (no special storage needed); on an iCloud Drive / Mac-local vault you can instead drop capture files into your configured inbox folder. Step-by-step Shortcut recipes are in How logging works below.

Nothing else is required — daily notes, the budget note, and the inbox folder are all created for you on demand.

Finance hub

Command: Open finance hub · ribbon wallet icon · Hub in the Daily budget sidebar

One view for everything beyond logging, in tabs:

Tab What's there
Today The Daily budget panel (today, this period, left per day, budgets, bills due), goal and trip prompts, and your shares' move today.
Inbox Bills that are overdue or due soon (with Mark paid), payments that look recurring but belong to no bill, every uncategorised entry grouped by merchant, and captures that failed. The tab's badge counts all of them.
Budgets This week or month (whichever periods your budgets use): budget bars, uncategorised callout, daily spend and the category donut.
Bills The full bills list: overdue, due soon, later, the payment calendar and suggestions.
Goals & trips Every goal with Contribute, New goal, trip mode, and each trip's dates.
Portfolio Holdings with sparklines, dividends to log, your watchlist, and a page for each ticker.
Reviews A week, month, quarter or year with every dashboard section. Step back and forward with ‹ ›; Copy as text copies a frozen review to paste into a note.

Every tab has its own command (Open finance hub: bills, and so on), so any of them can have a hotkey. The hub remembers its tab. It sits alongside the Daily budget sidebar rather than replacing it, and every code block keeps working inside notes.

Everything stays current. When a daily note, budget, goal, bill or the portfolio note changes — typed here, synced from your phone, or written by the plugin — the hub, the sidebar and every finance block open in a note refresh once, half a second later. A block you're typing into waits until you click away.

How logging works

Every transaction is a bullet under a ## Finance heading in a daily note (…/YYYY/MM/YYYY-MM-DD.md). The plugin maintains the checkbox total automatically:

## Finance
- [ ] #log/spending 16.20
    - $12.00 #log/spending/food/restaurants
        - Nobu
    - $4.20 #log/spending/food/snacks

The same thing rendered in a real daily note:

A daily note with a Finance section of logged spending bullets

You rarely type this by hand. Six ways to log:

Method Opens Obsidian? Use it for
obsidian://finance-capture URL yes, briefly phone capture with any sync (incl. Obsidian Sync)
Batched queue (?lines=) once per flush high-volume phone capture — queue all day, flush once
GitHub gist no silent phone capture on any sync; the only method that works from an Apple Watch
Capture inbox file no Files-writable vaults only (iCloud Drive / Mac-local)
Quick add modal (command or status bar) — logging while you're in Obsidian
Type the bullet yourself — edge cases; the total self-heals on note open

The first four are capture methods, and each has its own toggle in Settings → Capture methods. They are designed to run at the same time — see Running several methods at once for how the plugin stops that turning into double-logged transactions. Quick add and hand-typed bullets always work and have no toggle.

Which phone method? It depends on how the vault syncs, and on how much you spend:

  • Obsidian Sync (the vault lives inside the Obsidian app) → URL, batched queue, or gist. Shortcuts can't write into Obsidian's sandbox, so the inbox-file method won't work on the phone.
  • iCloud Drive / Mac-local folder → the inbox-file method also works (silent, no app launch), and the same folder lets Mac-side scripts and the in-app bank-CSV reconcile drop captures in.
  • A few transactions a day → plain URL is simplest: nothing to set up but a Shortcut.
  • Every tap-to-pay auto-logged → batched queue (one app switch a day) or gist (no app switch at all).

URL Shortcut (works with any sync)

A Shortcut opens obsidian://finance-capture?amount=12.5&merchant=Coles&category=food/groceries&source=manual. The plugin logs it to today's note. This briefly foregrounds Obsidian but needs no filesystem access.

The URL method also works as an automation — no Save File step needed on an Obsidian Sync vault. This is the actual automation used against an ANZ Plus card (source=anz): a Transaction trigger set to Run Immediately —

Automation trigger firing on an ANZ Plus card tap

— followed by URL-encoding the merchant, building the obsidian://finance-capture URL, and opening it:

Shortcut actions: URL Encode, Text, and Open URLs building the capture link

Shortcut D — "Log + confirm in Obsidian": build an Open URL action — obsidian://finance-capture?vault=<vault>&amount=12.5&category=food/groceries&merchant=Coles&source=manual — and run it from the Home Screen, Lock Screen, or Action Button. This is the only phone method that works on an Obsidian Sync vault; use it whenever you want the dashboard to update immediately.

Batched queue (works with any sync)

The cost of the URL method is that every tap-to-pay yanks you into Obsidian. The batched queue removes that: the automation appends each transaction to a list on the phone and does nothing else, and a second Shortcut flushes the whole list in one app switch.

Capture a queue of lines into lines=, newline-separated, in the same one-line format the capture inbox uses:

obsidian://finance-capture?lines=amount%3D12.50%20%7C%20merchant%3DColes%20%7C%20date%3D2026-07-30%0Aamount%3D4.20%20%7C%20merchant%3DBoost%20Juice%20%7C%20date%3D2026-07-30

Shortcut E — "Queue spend" (automation): Shortcuts → Automation → Transaction trigger, Run Immediately. Build one Text line — amount=[Transaction Amount] | merchant=[Transaction Merchant] | date=[Current Date · yyyy-MM-dd] | source=anz | id=[Current Date · yyyy-MM-dd'T'HHmmss]-[Random 1000–9999] — then Add to Variable → FinanceQueue, or append it to a Data Jar value if you want the queue to survive between Shortcut runs (it does not otherwise).

Shortcut F — "Flush spend queue": Get Value from Data Jar → Combine Text with New Lines → URL Encode → Text = obsidian://finance-capture?lines=[URL Encoded Text] → Open URLs → Delete Value from Data Jar. Put it on an Automation for a time of day, or on the Home Screen. Obsidian opens once, logs everything, and reports logged 7, skipped 1 duplicate.

Each line is parsed independently, so one malformed line never costs you the rest of the batch — bad lines land in Inbox/_failed/ with the reason, exactly like a bad inbox file. Including id= is worth the extra action: it means a re-run of the flush can never double-log.

GitHub gist (silent, works with any sync)

The only method that captures without opening Obsidian and still works on an Obsidian Sync vault. The phone appends a line to a private gist; the plugin polls the gist with Obsidian's own network layer (which works on iOS and Android), logs whatever is waiting, then clears it. It is also the only method that works from an Apple Watch, where obsidian:// cannot open anything.

Setup:

  1. Create a secret gist at gist.github.com with one file named finance-capture.txt and any placeholder content (a # queue comment line is ideal — comment lines are ignored). Copy the gist ID from its URL: the long hex string after your username.
  2. Create a fine-grained personal access token at GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens. Give it only the Gists: Read and write account permission — nothing else, no repository access — and the shortest expiry you can live with.
  3. In Obsidian: Settings → Finance Tracker → Capture methods → turn on GitHub gist, then fill in the gist ID, token, file name, and how often to poll. Hit Sync now to check it.

On the token. It is stored in this vault's data.json in plain text, which is how every Obsidian plugin stores settings. A Gists-only token can read and write your gists and nothing else, but treat it like a password: don't commit data.json, and revoke the token on GitHub if the vault is ever shared or synced somewhere you don't control.

Shortcut G — "Log spend (silent)": Get Contents of URL → https://api.github.com/gists/<gist-id>, Method GET, Headers Authorization: Bearer <token> → Get Dictionary Value files → finance-capture.txt → content. Then Text = the existing content, a new line, and your capture line. Finally Get Contents of URL → same URL, Method PATCH, same header, Request Body → JSON: {"files": {"finance-capture.txt": {"content": "[Text]"}}}.

That is a read-modify-write, so keep the token in the Shortcut (never in the vault) and don't run two flushes at the same second. The plugin's own drain is safe against this: it re-reads the gist before clearing and preserves anything that arrived mid-sync, and if the file was rewritten underneath it, it leaves the gist alone and says so rather than destroying captures.

The trade-off versus the URL methods: a gist write needs a connection. Shortcuts will fail the action offline, where opening obsidian:// would still have worked. If you're often offline, add an Otherwise branch to the Shortcut that falls back to the URL method.

Capture inbox (Files-writable vaults)

A Shortcut (or Mac script, or the bank-CSV reconcile) drops a one-line file into the inbox folder (default Utility/Finance/Inbox/); the plugin drains it into the right daily note on arrival and on launch. Capture line format — one line, key=value pairs separated by |:

amount=12 | cat=food/restaurants | merchant=Nobu | date=2026-06-10 | cur=AUD | source=apple-pay
Key Meaning
amount (amt, total) the amount to log — the only required key
cat (category) category path, e.g. food/groceries. Omit to log as uncategorized and categorise later.
merchant (payee, name) shown under the entry; also used to auto-guess the category from the merchant map
date YYYY-MM-DD; defaults to today. Set it for retroactive logging — the plugin routes to that day's note.
cur (currency) currency code; defaults to your vault default
origamt / origcur foreign amount + currency (travel); the holiday dashboard converts it
source free text, e.g. apple-pay, wise, manual
id (wiseid, ref) external id for de-duplication (used by Wise sync / CSV reconcile)

Bad files are moved to Inbox/_failed/ with the error, never dropped.

Shortcut A — "Log Spend" (manual, everyday) — put it on the Home Screen, Lock Screen, Action Button, and "Hey Siri, log spend":

  1. Ask for Input → Number → "Amount?"
  2. Choose from Menu → your categories + "Skip".
  3. Ask for Input → Text → "Merchant?" (allow empty).
  4. Text action: amount=[Provided Input] | cat=[Menu Result] | merchant=[Text] | date=[Current Date · yyyy-MM-dd] | source=manual (leave cat= empty if "Skip" was chosen).
  5. Save File → iCloud Drive → the inbox folder → "Ask Where to Save" off, "Overwrite" off. Filename: [Current Date · yyyy-MM-dd'T'HHmmss]-[Random 4 chars].txt.

Shortcut B — "Log Apple Pay" (automation, the important one) — for a card you don't sync via Wise: Shortcuts → Automation → Transaction trigger, filtered to that card, Run Immediately. Build the same Text line from Transaction Amount / Transaction Merchant, leave cat= empty (it auto-guesses from the merchant map or lands as uncategorized), add source=anz, then Save File to the inbox as above. Every tap-to-pay now auto-logs with zero interaction. Don't also make an Apple Pay automation for a card that's covered by Wise sync (below) — that would double-log it.

Shortcut C — "Log Spend (pick date)" — same as Shortcut A plus an Ask for Input → Date step feeding date=, for backfilling a day you forgot.

Bank-specific automated capture — Wise API sync and ANZ Plus CSV reconcile (click to expand)

These two are set up for the author's own accounts. The pattern generalises to any bank that exports a CSV or exposes an API, but nothing here is required — the URL shortcut and quick-add above cover everything.

Wise sync (covers all Wise spending, with real FX)

Wise personal API tokens support balance statements, so a scheduled Shortcut can pull every Wise transaction — card, online, transfers — including the real exchange rate for foreign spends. Keep the token in the Shortcut, never in the vault (generate it in Wise → Settings → API tokens; rotate or revoke it there if needed).

  1. Get Contents of URL → GET https://api.wise.com/v1/profiles, header Authorization: Bearer <token> → profileId.
  2. Get Contents of URL → GET /v4/profiles/{profileId}/balances?types=STANDARD → balanceId per currency.
  3. Get Contents of URL → GET /v1/profiles/{profileId}/balance-statements/{balanceId}/statement.json?currency=AUD&intervalStart=<lastSync>&intervalEnd=<now>&type=COMPACT.
  4. For each activity newer than the last sync, Save File one inbox file: amount=<spend> | merchant=<details> | date=<YYYY-MM-DD> | cur=AUD | source=wise | id=<referenceNumber> (add origamt=/origcur= for foreign spends).
  5. Store lastSync and schedule the Shortcut nightly. The id= field means re-runs never double-log.

ANZ Plus reconcile (catch what Apple Pay missed)

The Apple Pay automation only sees in-person taps — not online, direct debits, or BPAY. Monthly, export the bank CSV and run Reconcile a bank CSV; unmatched charges can be sent to the capture inbox. Matching is by date+amount, so already-logged taps aren't duplicated.

Running several methods at once

Every capture method has its own toggle in Settings → Capture methods, and they are meant to be combined — a bank automation feeding the queue, a gist for the Watch, quick add when you're at the desk. The risk in combining them is the same purchase arriving twice.

How duplicates are detected. The plugin keeps a rolling record of what each method has captured (the last 400, in data.json). A new capture is compared against it on amount + date + merchant, and is treated as a duplicate only when the earlier copy came in by a different method or from a different source=. That distinction is the whole point:

  • Two $4.20 Boost Juices on the same day, both from the ANZ automation → two real coffees, both logged.
  • One $12.50 Coles charge, once from the ANZ automation and once from the Wise sync → one purchase captured twice, logged once.

A missing merchant on one side still matches (bank feeds often carry a merchant the manual capture lacks, and vice versa), and the duplicate window — 1 day by default — allows for a feed that settles the day after the tap.

Setting Effect
Skip the second one (default) The duplicate is not logged. A notice names the method that got there first.
Log it, but tell me Both are logged, with a notice. Use this while you're still tuning which methods you want.
Log everything Detection off.

Quick add is exempt: it does its own "already logged today" check before you submit, so pressing the button always logs. A deliberate human action is never silently dropped.

Finding overlap. Settings → Capture methods shows a live Overlap check, and the Check capture methods for overlap command opens the full report: which pairs of methods have been capturing the same transactions, how often, and the most recent example. If one pair dominates, you're maintaining a method you could switch off. This is measured from what actually happened rather than guessed from what each Shortcut is supposed to cover.

Android

Nothing in the plugin is Apple-specific — the capture formats are a URL and an HTTP request, and Obsidian's mobile app handles both identically on Android. Only the automation app changes:

iOS Android equivalent
Shortcuts (manual run) HTTP Shortcuts (gist), or any launcher shortcut to an obsidian:// URL
Shortcuts Automation (Transaction trigger) Tasker or MacroDroid, triggered on a notification from your banking app
Data Jar (queue storage) Tasker variables or a local file
Action Button / Back Tap home-screen widget, or Tasker's Quick Settings tile

Two Android-specific notes:

  • There is no Apple Pay Transaction trigger. The usual substitute is a notification trigger on your banking app, parsing the amount and merchant out of the notification text with a regex. That is inherently bank-specific and breaks when the bank rewords its notifications, so treat it as best-effort and keep the monthly CSV reconcile as the backstop.
  • The gist method is the better fit on Android, because Tasker's HTTP Request action is first-class and you avoid the app-switch entirely.

Untested. The author develops on iOS and has no Android device, so the Android column above is reasoning from each app's documented capabilities rather than something that has been run. The plugin side is identical either way — if you use it on Android, corrections are welcome.

At current rates, Buy Me a Coffee needs to be clicked roughly 150 times before it becomes Buy Me A Second-Hand Pixel, at which point this section gets promoted from "reasoned about" to "actually tested". The finance tracker has, of course, already logged this as #log/spending/hardware/research and flagged it as over budget.

Deferred categorisation

Capture is instant and dumb; categorisation is a quick review later. Anything logged without a category, or guessed wrong, waits in the hub's Inbox — see Categorising.

Quick add modal

Command Quick add transaction (bind a hotkey) or click the status bar. One field, natural language, live preview:

12 nobu restaurants        $8 #transport Lime        4.50 coffee snacks @yesterday

First number = amount · a cat/sub, #tag or known category word = category · @date (ISO, yesterday, weekday, or anything the Natural Language Dates plugin parses) · the rest = merchant.

Quick add transaction modal with a split entry and a backdated entry

Foreign currency, without storing a rate. Put a currency code next to the amount you were charged, then the amount it actually cost in your home currency. Both are recorded; only the home amount counts toward budgets and totals.

58 USD : 83.64 obsidian sync #subscriptions/yearly/obsidian-sync

writes:

- $58.00 USD : $83.64 AUD #log/spending/subscriptions/yearly/obsidian-sync
    - obsidian sync

The code can go on either side of the number and the separator is optional, so 58usd 83.64, USD58 83.64 and $58 USD = $83.64 AUD all parse the same. The preview shows the implied rate (@ 1.4421) so you can see you typed it right — nothing stores it, and nothing converts anything for you. If you give only the foreign amount, quick add says so rather than guessing a rate.

Only real currency codes count, so 58 oak table is still $58 at "oak table".

Duplicate guard. If the same amount and merchant is already logged on that date, the modal says so before you add a second one — a double-tapped Shortcut is far more common than genuinely buying the same thing twice in a day.

Autocomplete — as you type, suggestions appear for categories, merchants, and people (owed=…), all derived from what you have actually logged plus your budget table — there is no category list to maintain. Arrow keys cycle, Tab or Enter accepts the highlighted suggestion, Esc dismisses. Once no suggestions are showing, Enter submits the entry — so typing a full line is just Enter-Enter-Enter through each token, finishing on a plain Enter with the popup closed. Accepting a known merchant also fills in its remembered category.

Date from the open note — with the Quick add uses the open daily note's date setting on (off by default), opening quick add while a daily note is active pre-fills that note's date, so backfilling an old day is frictionless.

Tag language

Kind Tag Example bullet
Spending #log/spending/<category>[/<sub>] - $12 #log/spending/food/restaurants
Income #log/income/<key> - $2400 #log/income/salary
Dividend #log/income/dividend/<ticker> - $8.20 #log/income/dividend/vas-ax
Savings contribution #log/income/<goalKey> - $500 #log/income/japanmidyear
Savings withdrawal #log/spending/goal/<goalKey>/<category> - $90 #log/spending/goal/rainy-day/medical
Holiday spend #log/spending/<year>/<key>/<category> - $40 #log/spending/26/japanmidyear/food
Recurring bill #log/spending/subscriptions/<cadence>/<name> - $12.99 #log/spending/subscriptions/monthly/spotify
Owed share (child line) #log/owed/<person> - owes: Sam $8.00 #log/owed/sam
Balance snapshot #log/balance/<account> - $5,230.00 #log/balance/anz-plus

The amount is a $-prefixed number on the bullet; a child line is the merchant, a second child is a note. Categories are slash paths (food/restaurants).

Because every entry is just a tag, Obsidian's own tag pane doubles as a category browser — nested paths become a real tree, with a live count per level:

Obsidian's tag pane showing the nested #log/spending category tree with counts

Categorising

Command: Open finance hub: inbox · the Inbox tab · Open inbox in the sidebar

The inbox holds every uncategorised entry, whatever its date, grouped by merchant so twelve rows of "SQ * Rode Fresh" are one decision. Each group suggests a category and says where the suggestion came from (a rule, or how the same shop was filed before). Apply to N files them all; the category picker has search, recent categories and + New. Captures that failed to parse are listed too, with Retry and Dismiss, and bills that are due or look recurring sit at the top.

Suggestions come from, in order: a merchant rule, a rule matching a chunk of the merchant ("woolworths" covers "Woolworths/cnr Brisbane H"), the same shop's past entries, then a shop with the same root. Quick add's preview shows the guess and why. Bill payments are never learned as a shop's everyday category.

Merchant rules live in plugin settings, not a note. Add or edit them in Settings → Categories (there's a box to test what a descriptor would be filed as), or tick Remember this merchant when you categorise something. Switching off Learn categories from past notes leaves only the rules. A Merchant Map.md note from an older version is read once and folded in; your own rules win, and Import merchant map note re-runs it.

Editing an entry (tap it in the inbox, the sidebar or a dashboard) changes the amount, category, merchant or date; a new date moves it to that day's note. It offers to apply the same category to other uncategorised entries from the shop.

Rename or split a category rewrites a category everywhere it appears — daily notes, the budgets table and merchant rules — or splits it by merchant (bare transport into public transport, rideshare and scooter). It previews every change first, touches only notes that still match, and names File recovery and Sync history as the undo.

Budgets

Budgets are a markdown table in Utility/Budgets/💸 Budgets.md:

| Name         | Category   | Limit | Period | Currency |
| ------------ | ---------- | ----: | ------ | -------- |
| Groceries    | groceries  |   140 | week   | AUD      |
| Shopping     | shopping   |   200 | month  | AUD      |
| All Spending | all        |   250 | week   | AUD      |

A real budgets note, with the free-form Notes section people tend to add below the table:

The Budgets note: the table plus a Notes section explaining Period/Category/all

  • Category is a top-level group (food) or a path (food/restaurants); all budgets everything.
  • Period: day, week, fortnight, month, bimonth, quarter, year. Limits scale by calendar days when shown over a different range (a weekly $140 shows as ~$600 on a monthly dashboard).
  • Bars are pace-aware: a marker shows where you should be today, the colour reflects whether you're ahead of pace (not just over the cap), and each bar shows the projected end-of-period spend and a safe $/day for the days left.
  • An all budget also drives the Left / Day card and the daily-spend trend line.
  • Trip-tagged spending never counts toward home budgets. An entry like - $40 #log/spending/26/japan/shopping is a withdrawal from that trip's savings goal: it shows on the holiday dashboard and reduces the goal, but is excluded from regular budgets, dashboards, the sidebar totals, and the forecast. Use type: all in a finance-query block for a report that includes trip entries.

Bills

Command: Open finance hub: bills · Log due bills · Insert a finance block → Recurring payments

Every bill is a note in Utility/Budgets/Bills/, with everything about it in its properties, so a bill is edited like any other note, including on a phone:

---
bill_id: spotify
bill_name: Spotify
aliases: [Spotify P0123ABC]
cadence: monthly
due_rule: day-of-month: 14
amount: 12.99
amount_model: fixed
reminder_days: 3
active: true
auto_log: false
next_amount:
change_date:
end_date:
payments_left:
next_due:
skipped: []
currency: AUD
---

Payments are the entries tagged #log/spending/subscriptions/<cadence>/<bill_id>, plus any entry whose merchant matches an alias. When a capture from a known bill arrives, it's filed to that bill automatically (with an Undo on the notice).

Due dates follow the bill's rule: after the last payment (the default), a day of the month, or an nth weekday (nth-weekday: 1 monday, -1 friday for the last). Schedules don't drift: paying a few days late doesn't push every later due date out. next_due overrides one cycle and clears itself once paid.

The Bills tab (and the finance-recurring block) groups bills as Overdue, Due soon (each bill's own reminder_days), Later this month and Later. Each row has Mark paid, and ⋯ for Push a week, Skip this cycle, Edit, Merge into another bill, Open note, Pause and End now. A skip is recorded on the bill; no $0 line is written. Above the list: cost per month and year, and due in the next 30 days. Below it: a payment calendar (1 month, 3 months, or a 12-month heat grid), Looks recurring payments that no bill claims yet (Track, Add to a bill, Ignore), and ended or paused bills.

Price changes go in next_amount and change_date. The edit dialog lays out the next eight cycles at the price each will actually be charged, and every total and projection follows it. amount_model: variable projects from the average of recent payments. end_date or payments_left retires a bill on its own.

Converting from the old model. Before 0.9, bills were detected from tags and tuned in a registry table in 🔁 Recurring Payments.md. That still works until you run Convert recurring payments to bill notes, which makes one note per bill, merges duplicate wordings into aliases, keeps cancelled bills as ended, and shows a preview first. Tidy up recurring payments removes same-day duplicate charges, old $0 skip lines and leftover registry rows, also behind a preview.

Runway

Command: Insert a finance block → Runway · Settings → Runway

How much do I need to keep available to be safe for the next month?

Runway answers that, and — once you choose the account it comes out of — whether you have it. It is a read-only figure: there is no envelope to fund and no bookkeeping. Pick a period and what counts, and it reads your bills:

The Runway block: the figure to keep available, per-week and per-day breakdowns, and every bill making up the total

Keep $395.27 available for the next 1 month Recurring bills only, between today and 2026-08-29 · 11 bills due

Three settings, in Settings → Bills and runway:

Setting Options
Runway period 1 week · 2 weeks · 1 month · 2 months · 3 months · 6 months
What counts Bills + usual spending (default), or recurring bills only
Account The account it comes out of (from your balance snapshots), or none

Against your balance. With an account chosen (or account: anz-plus in the block), runway compares itself with that account's latest balance snapshot: Covered, with $412.00 to spare — enough for about 41 days of outgoings, or Short by $180.00 — which runs out around 26 Sep. Days are walked through the window, so a bill counts on the day it lands. A snapshot more than two weeks old is flagged, since the answer is only as current as the balance.

The settings page shows the resulting figure live, so choosing a period is not abstract.

The figure walks your actual schedule. It is the sum of every bill occurrence that lands inside the window, not a monthly average scaled up. A $900 annual insurance renewal is worth nothing while it is eleven months away and worth all $900 the moment it enters the window — because that is the month you need the money. "Bills + usual spending" adds your average discretionary spend over the last 90 days, scaled to the window.

Every bill making up the total is listed with its date, soonest first, so the number is never a black box. There is also a per week and per day breakdown. The same card also appears at the bottom of the Bills tab.

If you tracked a bill reserve in 0.6, those #log/income/billreserve bullets are left alone. They no longer feed a balance, but they still count as transfers rather than income, so your reviews and forecasts are unaffected.

Goals and trips

Commands: Create savings goal · Contribute to a goal · Withdraw from a goal · Start trip mode · End trip mode · the hub's Goals & trips tab

Savings goals and trips share one frontmatter schema. Any goal with target_amount and due_date shows sinking-fund maths: the set-aside needed per week, and whether you're ahead of or behind a steady pace since your first contribution (with no contributions yet it says nothing saved yet). A trip is a goal that also has a trip_tag, dates and a currency.

Creating one asks for a name, a target and an optional due date. The tag its entries use is made from the name and shown as you type (Contributions are logged as #log/income/house-deposit), kept clear of goals and income categories already in use; Advanced lets you choose it yourself. A new trip takes its year from the name or start date (2027/new-zealand) and asks for its currency.

---
goal_name: Roadbike
goal_key: roadbike
target_amount: 3000
starting_balance: 0
due_date: 2026-12-10
active: true
currency: AUD
---

```savings-dashboard

A trip goal adds the trip keys (and optionally `trip_currency` for trip-mode capture):

```md
---
goal_name: Japan Mid-Year
goal_key: japanmidyear
target_amount: 6000
due_date: 2026-06-18
trip_tag: 26/japanmidyear
trip_currency: JPY
start_date: 2026-06-21
end_date: 2026-07-08
total_budget: 6000
currency: AUD
exchange_rates: JPY=0.00877
---

Contributions are - $500 #log/income/roadbike bullets; withdrawals are - $90 #log/spending/goal/roadbike/<category>, and don't count as home spending. Contribute and Withdraw share one dialog, with the goal typed and autocompleted rather than picked from a list. Goals are virtual envelopes: nothing has to move between real accounts.

Prompts

When a goal or trip needs a decision, a card says so at the top of the sidebar and the hub's Today and Goals & trips tabs:

When It offers
A goal is due within three days Contribute, New due date
A goal's due date arrives or passes Archive goal (after a confirmation), New due date
A goal reaches its target Archive goal
A trip's start date arrives Start trip mode
A trip has ended but trip mode is on End trip mode
A trip is over Archive trip

Each can be put off until tomorrow (Not now) or dismissed. A dismissed prompt comes back if its date changes.

Trip mode and exchange rates

While trip mode is on, quick add and URL captures default to the trip's tag and currency, converting to your home currency through the note's exchange_rates (JPY=0.00877: one yen is worth 0.00877 of your home currency) or dated exchange_rate_periods. The sidebar shows spent today, what's left of the trip budget and a safe amount per day. Add trip exchange rate has Fetch current rate, which fills in the European Central Bank's reference rate for the day; card and cash rates are usually a little worse, so adjust it if you know yours.

Goals overview block

Command: Insert a finance block → Goals

```finance-goals
account: short-term-savings   # optional — reconcile against a real account
```

One card per goal: saved vs target, the weekly set-aside still needed, ahead/behind pace, and a Contribute button. With account: it compares the sum of your goal envelopes against that account's latest #log/balance/… snapshot and shows the unallocated remainder — the piece of the lump sum not yet promised to any goal (or a warning when you've over-allocated).

Several trips, and archiving

Commands: Archive finished trips · Archive completed goals · the prompts' Archive button

You can save for several holidays at once — every goal note with active: true shows in the sidebar and counts toward forecast set-asides, and capture routes to whichever trip's dates match.

When a trip is over — or a savings goal has hit its target — archive it. Archiving writes a frozen Archive summary into the note: the savings steps (every contribution, dated), withdrawals, and for trips how the money was spent during the trip and after its end date. The note is then marked archived: <date> and moved to the archive folder. The note keeps its full history and its dashboards still render when you open it, but it leaves the active set: no more capture routing, sidebar cards, or forecast set-asides.

## Archive summary (2026-07-25)

- Target: $3,500.00
- Saved: $3,500.00 (100% of target) — $500.00 starting balance + 2 contributions

### Savings steps

| Date       |    Amount | Note             |
| ---------- | --------: | ---------------- |
| 2026-05-01 | $1,500.00 | Savings transfer |
| 2026-06-01 | $1,500.00 | Savings transfer |

### How it was spent

- Trip budget: $3,500.00
- Spent during the trip: $2,914.00 across 41 entries
- Spent after 2026-07-24: $40.00 across 1 entry

Dashboards

Add a fenced code block to any note; each reads transactions from your daily notes.

```finance-dashboard
period: week        # day | week | fortnight | month | bimonth | quarter | year
groupBy: primary    # primary | full
currency: AUD       # optional override
start: 2026-06-01   # optional explicit range (needs end)
end: 2026-06-30
title: June Spending
show: defaults, merchants   # optional: which sections, in this order
hide: trend                 # optional: sections to leave out
```

Sections

Section Shows
summary Total, average per day, change vs the previous period, top category.
income Income, spent, saved and savings rate = (income − home spending) ÷ income. Goal contributions, settle-ups and trip spending are transfers, so they're left out. With no income logged it says so rather than showing a rate.
uncategorised How many entries (and how much) have no category, with Open inbox. Only appears when there are some.
categories The category donut.
trend Daily spend with your budget line (periods up to 62 days).
changes The categories that moved most since the previous period, either way.
merchants Top five merchants, with branches of one shop grouped together.
largest The five largest transactions (your share of a split). Tap one to edit it.
budgets Pace-aware budget bars.
bills Bills paid this period; for a period that's still running, what's still due and what's due next period.
trips Trip spending, which never counts toward home totals.
savings Savings contributions this period.
portfolio Trades, dividends and — when there's price history — the change in value. Never fetches prices.

Defaults: period: week and period: month show every section. Other periods show what dashboards always did — summary, categories, trend, budgets, savings — plus the uncategorised callout. Sections with nothing to say stay hidden, so a quiet week doesn't fill up with empty cards. show: lists the sections you want in the order you want them (defaults and all expand in place); hide: removes some. Your existing weekly and monthly notes pick up the new sections without any edits.

"The previous period" is the previous calendar period: September is compared with August, a week with the week before.

The donut is a three-ring category donut — inner ring is the major categories, middle ring is each subcategory as its own colour section (a shade of its parent's hue), and the outer ring splits each subcategory further into its own leaf items — with a nested legend — a daily-spend sparkline with your budget line, pace-aware budget bars, and savings activity. Export CSV from the header. (The sidebar's mini pie stays at major categories; the donut falls back to a flat pie when nothing has subcategories.) A category that's only two levels deep (e.g. shopping/amazon, nothing beneath it) has no leaf level to split into, so its outer-ring band just continues as one uninterrupted block in the same colour rather than an arbitrary extra seam. Shades within a ring are ranked by spend — the biggest item gets the lightest shade of that hue, the smallest the darkest — and hovering any slice (at any of the three levels) shows its name, amount, and share of the total.

Finance dashboard donut chart with a hover tooltip on a subcategory slice

holiday-dashboard — planned vs actual trip spend, per-day budget remaining, and a trip calendar. Reads a goal note that has a trip_tag (see Goals), plus its Planned/Allocated tables. Once the trip has ended (past end_date, or the note is archived) the same block automatically becomes a trip reflection: total and after-trip spend, how it landed against the budget, average per day, biggest and quietest days, a per-category table (total, avg/day, share, and the biggest single expense with its merchant), a spend-by-day chart, and planned-vs-paid. Force either mode with view: live or view: reflection.

Trip reflection: category breakdown, spend-by-day chart, and planned vs paid

savings-dashboard — per-goal progress, contributions, sinking-fund set-aside and pace. Reads a goal note (frontmatter goal_key, target_amount, due_date, …).

Savings dashboard: target, saved, pace, and required-this-period cards

Every chart shares one hue-family colour system: each major category gets a base hue, its subcategories render as lighter/darker shades of that hue, and pies and legends rank by major-group total with subgroups nested beneath.

Chart grouping and the budget period are in Settings → Budgets and reviews; the week start is in General.

Reviews

Commands: Insert weekly review · Insert monthly review · Insert a finance block → Weekly review / Monthly review / Quarter in review / Year in review · Copy as text in the hub's Reviews tab

A review is not a live block. It works the numbers out once and inserts finished markdown at your cursor, so the note still says the same thing a year from now. The period is the note's own: a review inserted into your W19 note covers week 19, and one inserted into 2026-07.md covers July, whenever you get round to writing it up. Outside a periodic note it covers the current period.

A weekly or monthly review has what you spent (and the change from the period before), income, what you saved and your savings rate, uncategorised entries, bills paid, trip spending, a table of where the money went with each category's change, top merchants, the largest transactions, and any transfers:

## Finance review: week of 7 Sep 2026

- Period: 2026-09-07 to 2026-09-13
- Spent: $801.73 (▲ $661.73 (+473%) vs previous week)
- Income: $2,050.00
- Saved: $1,248.27 (61% savings rate)
- Uncategorised: 1 entry, $33.23
- Bills paid: 1 ($66.50)
- Trip spending, not counted above: Japan $210.00

### Where it went

| Category | Spent | Share | vs previous week |
| --- | ---: | ---: | ---: |
| Medical | $480.00 | 60% | ▲ $480.00 |
| Food | $210.00 | 26% | ▲ $110.00 |

### Top merchants

| Merchant | Spent | Visits |
| --- | ---: | ---: |
| The Good Group Cli | $480.00 | 1 |
| Woolworths | $150.00 | 2 |

### Largest transactions

- 2026-09-09 · The Good Group Cli · Medical · $480.00

A quarter or year review has total spent and income, the best and worst month by spend, the top spending categories with their share, and a transfers summary (savings contributions and withdrawals, settled split repayments, runway contributions):

## 2026 Year in Review

- Period: 2026-01-01 to 2026-12-31
- Total spent: $18,240.55
- Total income: $64,000.00
- Best month (lowest spend): 2026-02 — $980.10
- Worst month (highest spend): 2026-07 — $4,011.45

### Top spending categories

| Category | Total | % of spend |
| --- | ---: | ---: |
| Food | $5,120.30 | 28% |
| Subscriptions | $2,890.00 | 16% |

### Transfers

- Savings contributions: $3,000.00 (4)
- Savings withdrawals: $250.00 (1)
- Settled repayments received: $120.00 (2)
- Runway contributions: $400.00 (4)

Running one again later gives a fresh snapshot with whatever you've logged since.

Accounts & portfolio

Commands: Snapshot balances · Open portfolio · Log a trade · Refresh share prices · the hub's Portfolio tab

Everything here is arithmetic on your own records. It is not financial or tax advice, and the capital-gains flag is a reminder to check, not a ruling.

Account balances

Snapshot balances logs one bullet per account into today's daily note. Accounts you've snapshotted before are pre-filled, and the account box suggests the ones you've used — including the source= names your captures carry, like anz:

Snapshot balances modal, pre-filled with the last known balance

- $5,230.00 #log/balance/anz-plus
- $812.40 #log/balance/wise

The portfolio

Shares and ETFs live in a note, Utility/Finance/📈 Portfolio.md, as a table of trades — hand-editable, and the only record the plugin needs. Log a trade writes a row for you.

| Date | Type | Ticker | Units | Price | Fees | Currency | AUD cost | Account | Note |
| --- | --- | --- | ---: | ---: | ---: | --- | ---: | --- | --- |
| 2026-03-02 | buy | VAS.AX | 50 | 98.20 | 9.50 | AUD | | Pearler | |
| 2026-06-10 | buy | AAPL | 5 | 190.00 | 2.00 | USD | 1455.20 | Stake | |
| 2026-08-01 | split | AAPL | 2 | | | | | | 2-for-1 |
  • Type is buy, sell, drp (dividend reinvestment) or split. For a split, Units is the ratio: 2 for a 2-for-1, 0.5 for a 1-for-2 consolidation.
  • Tickers: ASX codes end in .AX; US tickers are written plain.
  • AUD cost matters for anything bought in another currency: it is what actually left your account, brokerage included. Leave it out and the cost is estimated at the current exchange rate, and flagged.
  • Dividends go in your daily notes as income, so they count everywhere income counts: - $12.40 #log/income/dividend/vas-ax. With prices from Yahoo you rarely type these yourself — see Dividends to log below.
  • Buying shares is a transfer, not spending. Trades never enter a daily note, so they never touch a budget.

The finance-portfolio block (already in the note, and the hub's Portfolio tab) shows:

  • value, cost base, gain, today's move, realised gains, twelve months of dividends and an annualised return;
  • holdings, first in first out, with brokerage in the cost base, each with a sparkline of its last month;
  • Dividends to log and your watchlist (below);
  • allocation by market and holding, value against cost over time, dividends with yield on cost, and every trade.

A holding's page. Tap a holding, or a watchlist ticker, for its price over 1M, 3M, 6M, 1Y or 2Y with your buys and sells marked as dots, your average cost as a dashed line and ex-dividend dates as ticks underneath; then your units, value, gain, parcels (flagging those held twelve months), recent dividends, Log trade already filled in with the ticker, and Open on Yahoo Finance. It draws from prices already fetched, so opening it never makes a request.

Watchlist. Follow a share or ETF without owning it: Add to watchlist (it searches as you type) saves it in the note's watchlist property, e.g. watchlist: [VGS.AX, NDQ.AX], which you can also edit by hand. Each ticker shows its price, today's move, the last month's change and a sparkline.

Dividends to log. Yahoo publishes each holding's dividends: the ex-date and the amount per unit. The portfolio works out how many units you held the day before each ex-date (buying on the ex-date doesn't earn that dividend), and lists any dividend in the last twelve months with nothing logged near it, and no reinvestment either, as VAS.AX · ex 2026-07-01 · 20 units × $0.49 = $9.80. Log it opens it with that estimate and a paid-on date to confirm or correct (withholding and rounding change the real figure), then logs it as income in that day's note. Dismiss stops listing it. They also appear in the hub's Inbox.

Today in the hub shows a Shares today card: the day's move in dollars and percent, the biggest mover, and any dividends to log.

Where prices come from

Settings → Portfolio → Price source:

Source Network Notes
Typed in (default) none Put prices in the note's properties: price_overrides: VAS.AX=103.42, AAPL=229.10 and fx_rates: USD=1.51. Always works.
A published Google Sheet Google Free, reliable, and yours. Settings gives you a template to paste into a new sheet — a row per ticker, GOOGLEFINANCE formulas already written — then publish it as CSV and paste the link.
Yahoo Finance Yahoo Free, covers the ASX, US and London (prices in pence become pounds), and the only source with price history (the charts) and dividend history (Dividends to log). Unofficial: Yahoo only answers requests that look like a web browser's, so the plugin's requests identify as one. It could stop working without notice.

However prices arrive, they are cached, so the portfolio still shows offline or while a source is refusing — with old prices marked as old. Yahoo has two servers, and a refusal from one is tried on the other; a source that refuses outright is backed off (2 minutes, doubling, up to six hours), and prices you type in always win. Prices are only fetched when the portfolio block is opened or you run Refresh share prices; there is no background polling.

There is no way to use the Stocks app on a Mac or iPhone: it has no API, and its prices are not available to other apps.

Net worth

```networth-dashboard
```

Net worth is your account balances plus the portfolio, at the prices already held — this block never fetches prices itself. The line over time carries each forward from its own last point.

Net worth block: total, accounts, and the balance-trend card

Split expenses

Command: Settle up split expenses · Insert a finance block → Split expenses

Quick-add and obsidian://finance-capture accept split=N (even split — your share is amount ÷ N) and owed=Name:$X tokens:

24 nobu restaurants split=2          → you owe $12, someone owes you $12
30 dinner restaurants owed=Sam:$10   → Sam owes $10 of the $30

The full amount stays on the bullet, with a hand-editable child line per person. Only your share counts toward budgets:

    - $24.00 #log/spending/food/restaurants
        - Nobu
        - owes: Sam $12.00 #log/owed/sam

The ```finance-splits``` block and a sidebar card sum outstanding balances per person. Settle up logs the repayment as income (- $12.00 #log/income/settleup/sam) and appends · settled <date> to the owed lines.

Settle up split expenses modal, showing nothing outstanding

Forecast

Command: Insert a finance block → Forecast

```finance-forecast
months: 6
```

Projects recurring income, minus recurring bills, minus your trailing-90-day average discretionary spend, forward N months — including committed goal set-asides — as a line chart with a ~$X by <date> headline. Override any input with income:, bills:, discretionary:, setaside:, or start:.

Query block

Command: Insert a finance block → Query

A read-only report over your entries — filter by category, tag, merchant, or date range; group by category, merchant, or month; sum or count:

```finance-query
period: month        # or start: / end: dates
category: food       # optional prefix filter
merchant: nobu       # optional substring filter
type: spending       # spending | income | all
group: category      # category | category-full | merchant | month | none
op: sum              # sum | count
view: table          # table | categories | bars | income-expense | cumulative
```

Views: table (grouped sums), categories (ranked category table with percentages), bars (ranked bars), income-expense (monthly income-vs-expense bars), cumulative (cumulative balance line).

Daily budget sidebar & status bar

The Daily Budget sidebar (ribbon coin icon) shows today + period spend, a Left/Day card, a mini pie, compact pace-aware budget rows (tap a row for the detail), savings goals, split balances, a Recurring bills due card, and a Needs a category card counting everything uncategorised, with Open inbox. Hub opens the finance hub.

Daily budget sidebar: today and fortnight totals, a category pie, pace-aware budget rows, savings goals, and a recurring bill due with a filled Log now

Recurring bills due lists every overdue or due-today bill, and stays until each is paid, so it can't get lost among the rest of the sidebar. Goal and trip prompts appear just under the totals.

Tap an uncategorised entry to edit it, or Open inbox to work through the lot (see Categorising).

Needs a Category triage card for an uncategorised entry

Edit transaction modal: category chips and the remember-merchant checkbox

The status bar shows 💸 Today $X · Week $Y · 📥 N (N = pending captures); click it to quick-add.

Reconciling against the bank

Command Reconcile a bank CSV: paste an ANZ or Wise export. Rows are matched by date+amount (so merchant-name differences don't cause duplicates); unmatched charges can be sent to the capture inbox to log and triage.

Commands

Run any of these from the command palette (Cmd/Ctrl+P). Obsidian prefixes each with Finance Tracker:. None has a default hotkey; every one can take yours.

Logging

Command What it does
Quick add transaction One field, natural language, live preview. Also the status bar.
Snapshot balances One balance bullet per account into today's note, pre-filled with each account's last balance.
Settle up split expenses Outstanding split balances per person; settling logs the repayment as income.
Process capture inbox · Sync capture gist now Drain those capture methods now rather than on their schedule.
Check capture methods for overlap Which pairs of methods have been logging the same transactions.
Reconcile a bank CSV Match an ANZ or Wise export by date and amount; send misses to the capture inbox.

Hub and views

Command What it does
Open finance hub The finance hub (ribbon wallet icon).
Open finance hub: today / inbox / budgets / bills / goals & trips / portfolio / reviews The hub on that tab.
Open daily budget The Daily budget sidebar (ribbon coin icon).
Open budgets note · Open recurring payments note · Open portfolio Open (creating if needed) that note.

Categories

Command What it does
Rename or split a category Rename everywhere, or split by merchant. Preview first.
Import merchant map note Re-read Merchant Map.md into the merchant rules.

Bills

Command What it does
Log due bills Log every bill whose due date has arrived, catching up missed cycles.
Convert recurring payments to bill notes One note per bill from the old tag-and-registry model. Preview first.
Tidy up recurring payments Remove same-day duplicate charges, $0 skip lines and leftover registry rows. Preview first.

Goals and trips

Command What it does
Create savings goal Name, target and optional due date; the tag is made from the name.
Contribute to a goal · Withdraw from a goal Log money into or out of a goal.
Start trip mode · End trip mode Point quick add and URL capture at a trip's tag and currency, and back.
Add trip exchange rate Add a rate to a trip note, with Fetch current rate.
Archive finished trips · Archive completed goals Write a frozen summary into each and move it to the archive folder.
Convert legacy trip tags Rewrite trips filed under #log/archive/<year>/<trip>/… to the current format. Preview first.

Portfolio

Command What it does
Log a trade Add a buy, sell, reinvestment or split to the Trades table, with ticker search.
Refresh share prices Fetch prices now, unless the source is backing off after refusing.

Notes and reviews

Command What it does
Insert a finance block Pick a block — dashboard, bills, goals, splits, forecast, accounts & portfolio, portfolio, query — or a frozen review, and insert it at the cursor.
Insert weekly review · Insert monthly review A frozen review of the note's own week or month.

Maintenance

Command What it does
Repair daily note totals Recompute every daily note's running total in one pass.
Export transactions to CSV Every transaction, with an entry_type column so income and balances aren't mistaken for spending.
Set up finance notes The setup wizard; creates missing starter notes and never overwrites one.

Settings

Settings follow the hub's areas, with a link to each at the top:

Section What's there
General Currency, week start, a live line saying how many entries the plugin can read (so a wrong folder is obvious), and Open finance hub.
Capture Quick add's date, opening the note after a capture, each capture method on or off, duplicate handling, the gist, and (under Advanced) the note format.
Categories Learn categories from past notes, and the merchant rules: add, edit, test and remove.
Budgets and reviews The sidebar's budget period, chart grouping, and the budgets note.
Bills and runway The recurring tag prefix, auto-log, sort order, every running bill with Active and Auto-log, the payment calendar range, and runway's period, what counts and account.
Goals and trips Goals and trips, with trip mode and archiving.
Portfolio The price source, the sheet link and a template for it, and how often prices refresh.
Files and setup Folder and note locations, and the setup wizard.

The daily-note folder and date format are detected from the Journals community plugin or the core Daily notes plugin when present. Settings are stored in the plugin's data.json, which also holds the gist token if you use one — keep it out of anything you share.

Limitations

Worth knowing before you install:

  • You have to tag things. There is no bank connection and no receipt OCR. Capture is fast (a Shortcut on an Apple Pay tap, or one line in quick add) but a transaction only exists once something writes the bullet.
  • No bank sync. The CSV reconcile tells you what you missed; it does not import. Deliberate — a bank connection would mean credentials and a network.
  • Mobile capture needs a Shortcut (or the quick-add modal). The obsidian:// URL works with any sync; the file-based capture inbox needs a vault your Files app can write to.
  • Multi-currency is trip-shaped. One home currency plus date-ranged rates per trip. If you hold two currencies permanently, this is not the model.
  • Amounts are per-note, not double-entry. There are no accounts and no balancing — a bullet is a bullet. Balance snapshots cover net worth instead.
  • No credit-card statement tracking (limits, utilisation, closing dates).
  • Portfolio figures are arithmetic, not advice. Prices are as fresh as their source; the capital-gains flag is a reminder to check, not a tax ruling.

Development

npm test          # checks main.js is in sync with its sources, then runs node --test
npm run build:main   # regenerate main.js from finance-core.js + src/

main.js is the file Obsidian loads: one file, no bundler, committed and attested by the release workflow. It is generated — do not edit it by hand. Two sources feed it:

  • finance-core.js — the pure logic, and the only file the unit tests import. It becomes the core IIFE at the top of main.js.
  • src/*.js — the plugin itself (settings, commands, views, modals, the settings tab), concatenated in file-name order. Fragments are copied verbatim, so each one is ordinary readable JavaScript.

scripts/build-main.js performs both steps, and npm test fails if main.js has drifted from its sources. The core transform is deliberately dumb: drop the leading "use strict", indent by two, turn module.exports = { into return {, and wrap it in the IIFE that replaces the //@@CORE@@ placeholder in src/00-header.js.

This started as a convention maintained by hand. By 0.6.0 it had quietly drifted in four places — including a default that differed between the tested code and the shipped code — so now a script owns it.

Tests are in three files:

  • tests/finance-core.test.js — unit tests for individual core functions.
  • tests/integrity.test.js — invariants across the whole write→read cycle: everything written parses back unchanged, and the running total on a note's root line always equals the entries beneath it. These guard the paths where a bug silently corrupts a user's notes rather than just showing a wrong number.
  • tests/capture-methods.test.js — a functional harness that loads the real main.js against a stubbed obsidian module and a stub vault, so plugin-side wiring is actually executed. It catches the classic failure where a core function lands but its caller never calls it.
HealthExcellent
ReviewSatisfactory
About
Log spending as tagged bullets inside your daily notes and keep running totals in plain Markdown—no separate database. Turn notes into spending, budget, holiday and savings dashboards and capture transactions from your phone or an inbox for quick entry.
FinanceDatesVisualization
Details
Current version
1.0.1
Last updated
2 days ago
Created
5 months ago
Updates
12 releases
Downloads
973
Compatible with
Obsidian 1.0.0+
Platforms
Desktop, Mobile
License
MIT
Report bugRequest featureReport plugin
Sponsor
Buy Me a Coffee
Author
AJAJarangutambo
antoinejhaddad.com/
GitHubarangutambo
  1. Community
  2. Plugins
  3. Finance
  4. Finance Tracker

Related plugins

Prisma Calendar

Prisma turns any note with a date into a flexible planning system inside Obsidian. There are no rigid schemas or predefined structures — just your data, your rules, fully under your control.

Yearly Glance

Year at a glance - overview of annual events with customizable management options.

Markwhen

Create timelines, gantt charts, calendars, and more using markwhen.

Advanced Canvas

Supercharge your canvas experience. Create presentations, flowcharts and more.

Excalidraw

Visual PKM powerhouse. Create and edit Excalidraw drawings.

Breadcrumbs

Visualise the hierarchy of your vault using a breadcrumb trail or matrix view.

Thino

Quickly capture memos and display them in the sidebar with a heatmap. (Closed source)

Tasks

Track tasks across your vault. Supports due dates, recurring tasks, done dates, sub-set of checklist items, and filtering. Maintained by Clare Macrae and Ilyas Landikov, created by Martin Schenck.

Day Planner

Turn tasks from daily notes, the Tasks plugin, and calendars into time blocks on an editable timeline, with built-in time tracker.

Maps

Adds a map layout to bases so you can display notes as an interactive map view.