159 lines
9.6 KiB
Markdown
159 lines
9.6 KiB
Markdown
# `portfolio.srf` reference
|
|
|
|
Your portfolio is a plain-text [SRF](https://git.lerch.org/lobo/srf)
|
|
file with **one lot per line**. A lot is a batch of shares of one
|
|
security bought on one date in one account. Positions are aggregated
|
|
from lots automatically.
|
|
|
|
zfin looks for `portfolio.srf` in `ZFIN_HOME` (or the current
|
|
directory). You can split holdings across several `portfolio_*.srf`
|
|
files; zfin union-merges every match (see
|
|
[Build your portfolio](../../guides/set-up-your-portfolio.md) for the
|
|
multi-file workflow).
|
|
|
|
## File format
|
|
|
|
Every SRF line is a comma-separated list of `key::value` pairs. Typed
|
|
values use a type tag:
|
|
|
|
- `key::value` -- string
|
|
- `key:num:value` -- number
|
|
- `key:bool:value` -- boolean (`true` / `false`)
|
|
|
|
The first line must be the version header `#!srfv1`. Lines beginning
|
|
with `#` are comments.
|
|
|
|
```srf
|
|
#!srfv1
|
|
# A stock/ETF lot
|
|
symbol::VTI,shares:num:100,open_date::2024-01-15,open_price:num:220.50,account::Brokerage
|
|
```
|
|
|
|
## Lot fields
|
|
|
|
| Field | Type | Required | Description |
|
|
|-----------------|--------|----------|---------------------------------------------------------------------------------------|
|
|
| `symbol` | string | Yes\* | Ticker or CUSIP. \*Optional for `cash` lots. |
|
|
| `shares` | number | Yes | Share count (or face value for cash/CDs). Negative for short option positions. |
|
|
| `open_date` | string | Yes\*\* | Purchase date `YYYY-MM-DD`. \*\*Not required for `cash`/`watch`. |
|
|
| `open_price` | number | Yes\*\* | Purchase price per share. \*\*Not required for `cash`/`watch`. |
|
|
| `close_date` | string | No | Sale date. Omit for an open lot. |
|
|
| `close_price` | number | No | Sale price per share. |
|
|
| `security_type` | string | No | `stock` (default), `option`, `cd`, `cash`, `illiquid`, `watch`. |
|
|
| `account` | string | No | Account name. Should match an `account::` entry in [`accounts.srf`](accounts-srf.md). |
|
|
| `note` | string | No | Free-text note (shown in cash/CD/illiquid tables). |
|
|
| `ticker` | string | No | Ticker alias used for price fetching when `symbol` is a CUSIP. |
|
|
| `price` | number | No | Manual price override (for securities the providers don't cover). |
|
|
| `price_date` | string | No | Date of the manual price (`YYYY-MM-DD`), for staleness display. |
|
|
| `drip` | bool | No | `true` if the lot is from dividend reinvestment (summarized as ST/LT groups). |
|
|
| `maturity_date` | string | No | CD maturity or option expiry date (`YYYY-MM-DD`). |
|
|
| `rate` | number | No | CD interest rate (e.g. `5.25` = 5.25%). |
|
|
|
|
## Security types
|
|
|
|
| Type | Meaning |
|
|
|-------------------|------------------------------------------------------------------------------------------------|
|
|
| `stock` (default) | Stocks, ETFs, mutual funds. Priced from Tiingo (Yahoo fallback), aggregated by symbol. |
|
|
| `option` | Option contracts. Shown separately; `shares` is the contract count (negative = written/short). |
|
|
| `cd` | Certificates of deposit. Shown by maturity with rate and face value. |
|
|
| `cash` | Cash, money-market, settlement balances. Grouped by account. |
|
|
| `illiquid` | Real estate, vehicles, etc. Excluded from the liquid total; included in Net Worth. |
|
|
| `watch` | Watchlist item: tracks price only, no position. See [`watchlist.srf`](watchlist-srf.md). |
|
|
|
|
## Examples
|
|
|
|
Each line below is valid on its own. These mirror the bundled
|
|
[`examples/`](../../../examples/) portfolios.
|
|
|
|
```srf
|
|
#!srfv1
|
|
# Stocks / ETFs (multiple lots of the same symbol aggregate)
|
|
symbol::VTI,shares:num:1100,open_date::2018-06-15,open_price:num:140.00,account::Pat 401k
|
|
symbol::VTI,shares:num:240,open_date::2015-01-08,open_price:num:103.40,account::Pat Roth
|
|
|
|
# Cash (no symbol, no open_date/open_price needed)
|
|
security_type::cash,shares:num:48000.00,open_date::2026-04-30,open_price:num:1.00,account::Joint taxable
|
|
|
|
# Closed (sold) lot
|
|
symbol::AMZN,shares:num:10,open_date::2022-03-15,open_price:num:150.25,close_date::2024-01-15,close_price:num:185.50
|
|
|
|
# DRIP lot (dividend reinvestment; summarized as ST/LT groups)
|
|
symbol::VTI,shares:num:0.234,open_date::2024-06-15,open_price:num:267.50,drip:bool:true,account::Brokerage
|
|
|
|
# CUSIP with a ticker alias for pricing (e.g. a 401k CIT share class)
|
|
symbol::02315N600,shares:num:1200,open_date::2022-01-01,open_price:num:140.00,ticker::VTTHX,account::Fidelity 401k,note::VANGUARD TARGET 2035
|
|
|
|
# Manual price override (security with no provider coverage)
|
|
symbol::NON40OR52,shares:num:500,open_date::2023-01-01,open_price:num:155.00,price:num:163.636,price_date::2026-02-27,account::Fidelity 401k
|
|
|
|
# Option: a written (short) call. Negative shares = contracts sold.
|
|
security_type::option,symbol::AAPL 06/20/2025 200.00 C,shares:num:-2,open_date::2025-01-15,open_price:num:12.50,option_type::call,underlying::AAPL,strike:num:200,maturity_date::2025-06-20,account::Brokerage
|
|
|
|
# CD
|
|
security_type::cd,symbol::912797KR0,shares:num:10000,open_date::2024-06-01,open_price:num:10000,maturity_date::2025-06-01,rate:num:5.25,account::Brokerage,note::6-Month T-Bill
|
|
|
|
# Illiquid asset (net worth only)
|
|
security_type::illiquid,symbol::HOME,shares:num:450000,open_date::2020-06-01,open_price:num:350000,note::Primary residence
|
|
```
|
|
|
|
## Price resolution
|
|
|
|
For stock lots, the displayed price is resolved in this order:
|
|
|
|
1. **Live API** -- latest close from cached candles (Tiingo, Yahoo fallback).
|
|
2. **Manual price** -- the lot's `price` field, for securities without coverage.
|
|
3. **Average cost** -- the position's `open_price`, as a last resort.
|
|
|
|
Manual-priced rows render in warning color so you know they may be
|
|
stale; `price_date` tracks when you last updated them.
|
|
|
|
## Ticker aliases and CUSIPs
|
|
|
|
Some securities (notably 401k CIT share classes) are identified by
|
|
CUSIP but have a retail-ticker equivalent for pricing. Use `ticker::`
|
|
so `symbol::` stays the display identifier while the alias drives API
|
|
calls:
|
|
|
|
```srf
|
|
symbol::02315N600,ticker::VTTHX,...
|
|
```
|
|
|
|
If the CUSIP and retail ticker have different NAVs (common for CIT vs.
|
|
retail funds), use a manual `price::` instead of `ticker::`. To resolve
|
|
a CUSIP to a ticker, use [`zfin lookup`](../cli/lookup.md).
|
|
|
|
## Advanced and option fields
|
|
|
|
These are less common but parse on any lot:
|
|
|
|
| Field | Type | Applies to | Description |
|
|
|-----------------|--------|---------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
| `price_ratio` | number | share classes | Multiplier applied to the fetched (alias) price to get the institutional NAV. E.g. if the retail class is $27.78 and the institutional class trades at $144.04, set `price_ratio:num:5.185`. |
|
|
| `underlying` | string | options | Underlying stock symbol (e.g. `AMZN`). |
|
|
| `strike` | number | options | Strike price. |
|
|
| `maturity_date` | string | options | Expiration date (`YYYY-MM-DD`). |
|
|
| `multiplier` | number | options | Shares per contract (default `100`). |
|
|
| `option_type` | string | options | `call` (default) or `put`. |
|
|
|
|
An option lot is defined by these explicit fields, not by decoding the
|
|
symbol -- `symbol` is just a display label, so set it to whatever your
|
|
brokerage shows (e.g. `AAPL 06/20/2025 200.00 C`). For a worked
|
|
two-lot example, see the covered call in
|
|
[Build your portfolio](../../guides/set-up-your-portfolio.md#example-a-covered-call).
|
|
|
|
## DRIP lots
|
|
|
|
Lots marked `drip:bool:true` are collapsed into short-term (ST) and
|
|
long-term (LT) groups in the position detail view (split on the
|
|
1-year capital-gains threshold) rather than listed individually.
|
|
|
|
## See also
|
|
|
|
- [Build your portfolio](../../guides/set-up-your-portfolio.md) -- the task-oriented walkthrough.
|
|
- [`accounts.srf`](accounts-srf.md) -- give each `account::` a tax type.
|
|
- [`metadata.srf`](metadata-srf.md) -- classify each `symbol::` for analysis.
|
|
- [`zfin portfolio`](../cli/portfolio.md) and [`zfin import`](../cli/import.md).
|
|
|
|
---
|
|
|
|
[Documentation home](../../README.md#reference)
|