154 lines
5.8 KiB
Markdown
154 lines
5.8 KiB
Markdown
# Snapshots and history
|
|
|
|
**Goal:** record your portfolio's value over time and review how it has
|
|
changed -- day to day, year over year, and between any two dates.
|
|
|
|
**You'll need:** a working portfolio. The
|
|
[`post-retirement`](../../examples/post-retirement/) example ships with
|
|
a `history/` folder of snapshots, so you can explore the read side
|
|
immediately:
|
|
|
|
```bash
|
|
ZFIN_HOME=examples/post-retirement zfin history
|
|
```
|
|
|
|
## The idea
|
|
|
|
zfin doesn't track your value automatically -- it reads what you have
|
|
*right now*. To build a time series, you write a **snapshot** each day
|
|
(or week), and the history/compare commands read those snapshots back.
|
|
|
|
Snapshots live in `<portfolio-dir>/history/<date>-portfolio.srf`. Each
|
|
is an immutable **valuation** record for one date: the portfolio's
|
|
totals, its per-account and per-tax-type values, and a per-lot
|
|
breakdown of where that value sat. It records what things were *worth*,
|
|
not the full detail of your lots -- see
|
|
[The snapshot model](../explanation/snapshots-model.md) for what is and
|
|
isn't captured, and why.
|
|
|
|
## 1. Write a snapshot
|
|
|
|
The simplest way is to run it yourself.
|
|
[`zfin snapshot`](../reference/cli/snapshot.md) computes today's
|
|
snapshot and writes it under `history/`. Try a dry run first -- it
|
|
computes and prints the snapshot without writing anything:
|
|
|
|
```bash
|
|
zfin snapshot --dry-run # compute + print, write nothing
|
|
zfin snapshot # write history/<today>-portfolio.srf
|
|
```
|
|
|
|
Run it whenever you want a record on the books -- after a monthly
|
|
review, say. The snapshot is just a file in `history/`; nothing else is
|
|
required.
|
|
|
|
**Back-filling a past date (optional, needs git).** If you keep your
|
|
portfolio file under [git](https://git-scm.com/) version control,
|
|
`--as-of` can reconstruct a snapshot for an earlier date: it recovers
|
|
your portfolio as it was then (from git) and prices it from the cached
|
|
price history.
|
|
|
|
```bash
|
|
zfin snapshot --as-of 2025-01-02
|
|
```
|
|
|
|
If you don't use git, skip this -- just snapshot going forward.
|
|
|
|
## 2. Keep it current automatically (optional)
|
|
|
|
Most people would rather not remember to run it every day. You can hand
|
|
that off to your operating system's **task scheduler** -- a built-in
|
|
service that runs a command on a set timetable, even while you're away.
|
|
|
|
**When to schedule it.** Run it in the early morning, *after* the prior
|
|
trading day's closing prices have posted. ETF and mutual-fund values
|
|
update overnight, and while data providers say "after midnight," in
|
|
practice **3:30am US Eastern** is the first time yesterday's closing
|
|
NAVs reliably land -- schedule it earlier and you risk capturing stale
|
|
prices.
|
|
|
|
**macOS and Linux** use `cron`. Run `crontab -e` and add a line like
|
|
this (3:30am, Monday-Friday -- adjust the hour for your machine's
|
|
timezone if it isn't US Eastern):
|
|
|
|
```cron
|
|
30 3 * * 1-5 cd ~/finance && /usr/local/bin/zfin snapshot
|
|
```
|
|
|
|
The five fields are minute, hour, day-of-month, month, day-of-week
|
|
(`1-5` = Mon-Fri); the full path to `zfin` matters because cron runs
|
|
with a minimal `PATH`. macOS ships cron, though the first run may prompt
|
|
you to grant your terminal "Full Disk Access."
|
|
|
|
**Windows** has no `cron` -- use Task Scheduler to run `zfin snapshot`
|
|
daily. (zfin should run on Windows, but it isn't regularly tested
|
|
there.)
|
|
|
|
## 3. Review the timeline with `history`
|
|
|
|
Run [`zfin history`](../reference/cli/history.md) with no symbol for the
|
|
portfolio-value timeline: rolling-window changes, a chart (an inline
|
|
Kitty image when your terminal supports it, else braille), and a
|
|
recent-snapshots table.
|
|
|
|
```bash
|
|
ZFIN_HOME=examples/post-retirement zfin history
|
|
```
|
|
|
|
```
|
|
Portfolio Timeline: Liquid
|
|
========================================
|
|
Change Δ % % / yr
|
|
1 year +$230,000.00 +9.79% +9.79%
|
|
3 years +$459,059.08 +21.64% +6.72%
|
|
5 years +$686,215.45 +36.24% +6.37%
|
|
All-time +$1,073,725.79 +71.28% +6.00%
|
|
```
|
|
|
|
Useful flags: `--metric liquid|illiquid|net_worth`, `--since` /
|
|
`--until` to bound the window, and `--resolution daily|weekly|monthly`.
|
|
|
|
> The percentage change includes contributions and withdrawals, not
|
|
> just market movement. To separate new money from market gains, use
|
|
> [contributions](track-contributions.md).
|
|
|
|
## 4. Compare two points with `compare`
|
|
|
|
[`zfin compare`](../reference/cli/compare.md) diffs two dates: liquid
|
|
totals, per-symbol price moves, and -- when your portfolio is tracked
|
|
in git -- contribution attribution. Pass one date to compare against
|
|
the live portfolio, or two dates to compare historical snapshots:
|
|
|
|
```bash
|
|
ZFIN_HOME=examples/post-retirement zfin compare 2024-04-01 2025-04-01
|
|
```
|
|
|
|
```
|
|
Portfolio comparison: 2024-04-01 -> 2025-04-01 (365 days)
|
|
|
|
Liquid: $2,350,000.00 -> $2,580,000.00 +$230,000.00 +9.79%
|
|
```
|
|
|
|
Arguments can be given in any order; output always reads older ->
|
|
newer. On a missing snapshot date, `compare` prints the nearest
|
|
available dates and exits rather than silently snapping. Add
|
|
`--projections` to include projected-return and safe-withdrawal deltas.
|
|
|
|
## Back-history without daily snapshots
|
|
|
|
If you have historical totals from a spreadsheet but no per-day
|
|
snapshots, record them in
|
|
`history/imported_values.srf` (one `liquid::` total per date). The
|
|
history and projection-overlay tools read it as a lower-fidelity
|
|
fallback when no native snapshot covers a date. The post-retirement
|
|
example includes one spanning 2016-2024.
|
|
|
|
## Next steps
|
|
|
|
- [Track contributions](track-contributions.md) -- separate new money from gains.
|
|
- [Plan for retirement](plan-retirement.md) -- overlay actuals on projections.
|
|
- [`zfin snapshot`](../reference/cli/snapshot.md) / [`zfin history`](../reference/cli/history.md) / [`zfin compare`](../reference/cli/compare.md)
|
|
|
|
---
|
|
|
|
[Previous: Track contributions](track-contributions.md) | [Next: Handle a stock split](handle-a-stock-split.md) | [Documentation home](../README.md)
|