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