# 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 record of totals, per-account values, and lot-level
state for one date.

## 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 braille chart, 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: Plan for retirement](plan-retirement.md) | [Documentation home](../README.md)
