zfin/docs/explanation/concepts.md
Emil Lerch 74fc219afd
All checks were successful
Generic zig build / build (push) Successful in 5m48s
Generic zig build / publish-macos (push) Successful in 11s
Generic zig build / deploy (push) Successful in 23s
add docs/guides
2026-06-22 14:53:53 -07:00

126 lines
6.8 KiB
Markdown

# Core concepts
A handful of ideas explain how zfin is put together. Once they click,
the rest of the tool is predictable.
## zfin is a reader, not a database
zfin doesn't store your portfolio. You own a few plain-text files; zfin
reads them, fetches market data, and computes. There's no hidden state,
no import step, no lock-in -- your data is text you can read, diff, and
version-control.
This is why almost everything is grounded in files you edit directly,
and why the docs can ship runnable [examples](../../examples/).
## The `.srf` files
You don't need any of these to look up a quote, trailing returns, or
earnings for a symbol -- those commands need only an API key. The files
matter only when you want zfin to track *your* portfolio, and you add
them one at a time as you go. In practice you start with **one** file,
`portfolio.srf`; everything else is optional, and zfin degrades
gracefully when a file is absent (the last column says what you give
up).
They all share one format: [SRF](https://git.lerch.org/lobo/srf)
(Simple Record Format) -- line-oriented, comma-separated `key::value`
pairs (`key:num:` and `key:bool:` for typed values), `#` comments, and
a `#!srfv1` header.
| File | Holds | When you need it |
|---------------------------------------------------------------------|----------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------|
| [`portfolio.srf`](../reference/config/portfolio-srf.md) | Your lots (positions, cash, options, CDs) | The one file to start with: required for any portfolio, analysis, or projection view. |
| [`accounts.srf`](../reference/config/accounts-srf.md) | Tax type / institution / account number / update cadence per account | Optional. Without it, accounts show as "Unknown" in the tax-type breakdown; everything else works. |
| [`metadata.srf`](../reference/config/metadata-srf.md) | Sector / geo / asset-class per symbol | Optional. Without it, the asset-class / sector / geography breakdowns have nothing to group by; valuation still works. |
| [`projections.srf`](../reference/config/projections-srf.md) | Retirement projection inputs | Only for `zfin projections`, which otherwise runs with sensible defaults. |
| [`watchlist.srf`](../reference/config/watchlist-srf.md) | Price-only symbols | Only if you want a watchlist. |
| [`transaction_log.srf`](../reference/config/transaction-log-srf.md) | Declared transfers | Only to refine contribution attribution; missing means it's simply not applied. |
A few more files show up only when you opt into a feature:
`history/*-portfolio.srf` snapshots are written for you by
[`zfin snapshot`](../reference/cli/snapshot.md), and
`~/.config/zfin/keys.srf` / `theme.srf` customize the TUI. The same SRF
format is used internally for the cache and snapshots, so those are
inspectable too.
## `ZFIN_HOME`: where your data lives
zfin resolves your files one of two ways -- never a mix of both:
1. **`ZFIN_HOME` is set** -- zfin reads from that directory, and only
there. The current directory is never consulted, so a stray file in
cwd can't silently shadow your real data.
2. **`ZFIN_HOME` is unset** -- zfin reads from the current directory.
To make a single run read the current directory while `ZFIN_HOME` is
set, unset it just for that command: `env -u ZFIN_HOME zfin portfolio`.
`accounts.srf` and `metadata.srf` are always loaded from the same
directory as the resolved `portfolio.srf`. Pointing `ZFIN_HOME` at an
example directory is what makes the guides runnable:
```bash
ZFIN_HOME=examples/post-retirement zfin portfolio
```
Keep your real data in a private `ZFIN_HOME` outside any repo so you
never commit holdings. See
[environment variables](../reference/config/environment.md).
## Live data vs. snapshots
zfin deals with two kinds of "your portfolio," and the distinction
matters:
- **Live (current) portfolio** -- computed from `portfolio.srf` plus
the latest prices. This is what `portfolio`, `analysis`, `review`,
and friends show. It always reflects what you hold *now*.
- **Snapshots** -- immutable records of your totals on a past date,
written by [`zfin snapshot`](../reference/cli/snapshot.md) into
`history/<date>-portfolio.srf`. These are the time series that
`history` and `compare` read.
The live portfolio is mutable (you edit it); snapshots are historical
facts (you don't). See
[Snapshots and history](../guides/snapshots-and-history.md).
## The data service and caching
All market data flows through one path: check the local cache, and if
the entry is fresh enough, use it; otherwise fetch from a provider,
write it to the cache, and return it. You rarely think about providers
directly -- you think about *freshness*, controlled by the
`--refresh-data` flag. See
[Caching and data freshness](caching.md) and
[Why multiple data providers](data-providers.md).
## CLI and TUI are two faces of one engine
The CLI and the interactive TUI (`zfin i`) sit on the same engine:
they read the same files, share the same cache, and run the same
analytics, so a figure you see in one matches the other. Reach for the
CLI for quick checks and scripting; reach for the TUI for browsing and
high-fidelity charts.
They overlap heavily but aren't a one-to-one mirror -- and aren't
trying to be:
- **CLI-only.** Several commands have no TUI tab: the data-hygiene and
journaling ones (`audit`, `snapshot`, `import`, `enrich`, `compare`,
`contributions`), plus a few like `exposure` and `milestones`.
- **TUI-only.** Interactive touches have no CLI counterpart: live
charts, in-place refresh, the `?` keybinding overlay, and
conveniences like the overlay that shows a holding's full name behind
its ticker.
The nine TUI tabs -- Portfolio, Analysis, Review, Projections, History,
Quote, Performance, Earnings, Options -- cover the browsing and
analysis surfaces; the rest lives on the CLI. See
[The interactive TUI](../reference/tui.md).
## Where to go next
- [Getting started](../getting-started.md) if you haven't installed yet.
- [Build your portfolio](../guides/set-up-your-portfolio.md) to create your first file.
- [Caching and data freshness](caching.md) for the fetch model.