7 KiB
A periodic review
Goal: on a regular cadence -- weekly works well -- make zfin agree with your brokerages, see what changed since last time, and commit the reconciled state so the next review has a clean baseline to compare against.
This is the loop that ties the other guides together. Each step has its own guide for the details; this one is the routine you actually run. It settles into well under an hour once it's habit.
reconcile ──► what changed? ──► (projections) ──► commit
(audit) (compare) (optional) (baseline)
▲ │
└──────────────── next review ◄────────────────────────┘
1. Reconcile against your brokerages
Pull a fresh export from each brokerage that offers one and drop it in
your audit/ folder (or wherever you've pointed $ZFIN_AUDIT_FILES --
see Audit against your brokerage for the
export steps and auto-discovery rules). Then:
zfin audit
Fix any flagged share or cash discrepancy in portfolio.srf and re-run
until it reconciles. A tight edit loop helps: if you have
watchexec installed,
watchexec -- zfin audit
re-runs the audit on every save, so the remaining-discrepancy list shrinks live as you fix lots -- much faster than alt-tab, rerun, read, alt-tab, edit.
Reconcile first, for a reason. Step 2 splits your change in value into contributions vs. market gains, and that split is only as honest as your share counts. Reconcile before you read the headline or the attribution will lie to you.
Blind spots the audit can't see
- Accounts with no export (some insurers, some 401(k)
recordkeepers) -- check the latest statement and update
portfolio.srfby hand. - Payroll-driven cash -- e.g. ESPP contributions that haven't purchased yet won't appear in a positions export until the purchase posts. Reconcile those against a paystub.
- A small, expected standing discrepancy -- some accounts just sit a few dollars off every week. Note it and move on rather than chasing it each time.
- Lagging transaction views. A brokerage's positions view can update overnight before its transaction view posts the dividend, interest, or option assignment that caused the change. Trust the positions numbers and reconcile the totals; the cause-side record catches up later and isn't needed to get today's counts right.
2. The headline -- what changed since last time
One command gives you the whole "since last review" picture:
zfin compare 1W --projections --commit-before HEAD
1Wis the point of comparison -- the snapshot from one week ago. Any relative shortcut or an explicitYYYY-MM-DDworks.--projectionsfolds in projected-return and safe-withdrawal (SWR@99%) deltas, then vs. now. (Costs ~1-2s per endpoint for the Monte Carlo search; add--no-eventsto exclude life events.)--commit-before HEADpins the contributions/gains attribution to your latest reconciliation commit. This matters -- see Attribution and commit timing.
Read off the liquid-total delta, the contributions-vs-gains split, the
per-symbol winners and losers, and the projection deltas. For most
weeks, this single command is the review. See
Snapshots and history for a full walk
through compare output.
3. (Optional) Full projections
compare --projections gives you the deltas but not the full benchmark
table or every scenario row. When you want the complete picture:
zfin projections # default: with life events (SS, college, ...)
zfin projections --no-events # baseline: life events excluded
zfin projections --as-of 1W # the same table as of last review
zfin projections --vs 1W # both ends of the window in one run
See Plan for retirement for what these rows mean.
4. Commit -- the baseline for next time
git add portfolio.srf metadata.srf history/
git commit -m "review 2026-06-20"
Committing does double duty:
- It snapshots the reconciled
portfolio.srf, and the day's snapshot file inhistory/rides along, so future--as-ofruns can read it. - zfin walks the git history of
portfolio.srffor contributions analysis, treating each commit as a reconciliation point. Commit timing sets next review's baseline -- a same-day commit keeps a weekly cadence clean.
If you keep your portfolio directory in git (recommended), this is also your backup and your audit trail.
Attribution and commit timing
compare and contributions work out "contributions vs. gains" by
walking the git history of portfolio.srf. The positional date (1W)
picks the snapshot whose prices you compare against; --commit-before
picks which commit anchors the attribution. Those two can drift apart.
If you reconcile on Saturday but don't commit until Monday, next
Saturday's 1W snapshot lands before your last commit -- so a bare
compare 1W would attribute two weeks of contributions to one week.
--commit-before HEAD sidesteps this by pinning attribution to your
most recent reconciliation commit regardless of the snapshot date. When
the dates line up anyway, the flag is harmless -- which is why it's
worth making a habit.
Relative dates
Every date-accepting command takes the same shorthand, so you rarely type a full date:
| Shortcut | Means |
|---|---|
1W |
one week ago |
3W |
three weeks ago |
1M |
one month ago |
1Q |
one quarter ago |
1Y |
one year ago |
compare, contributions --since/--until, projections --as-of/--vs,
snapshot --as-of, and history --since/--until all accept it (plus an
explicit YYYY-MM-DD).
If there's no snapshot yet
The comparison needs a snapshot to compare against. If your daily snapshot didn't run, or you're reviewing off your normal cadence, make one first:
zfin portfolio --refresh # fresh close prices for tracked symbols
zfin snapshot # writes history/<today>-portfolio.srf
See Snapshots and history for the cron setup that automates daily snapshots.
Next steps
- Audit against your brokerage -- step 1 in depth.
- Snapshots and history --
compare, snapshots, and the timeline. - Track contributions -- the contributions / gains attribution.
- Plan for retirement -- the projection rows.
compareandprojectionsreference -- every flag.
Previous: Audit against your brokerage | Next: Customize the TUI | Documentation home