# 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.
