201 lines
10 KiB
Markdown
201 lines
10 KiB
Markdown
# zfin
|
|
|
|
A financial data library, CLI, and terminal UI written in Zig. Tracks portfolios, analyzes trailing returns, displays options chains, earnings history, and more -- all from the terminal.
|
|
|
|
## Quick start
|
|
|
|
### macOS (Apple Silicon) -- pre-built binary
|
|
|
|
```bash
|
|
# Download the latest aarch64-macos binary, make it executable, drop on $PATH
|
|
curl -L -o zfin \
|
|
https://git.lerch.org/api/packages/lobo/generic/zfin-aarch64-macos/latest/zfin-aarch64-macos
|
|
chmod +x zfin
|
|
sudo mv zfin /usr/local/bin/ # or anywhere on $PATH
|
|
```
|
|
|
|
### Linux / building from source
|
|
|
|
```bash
|
|
# Requires Zig 0.16.0. With mise installed, `mise install` will pick the right
|
|
# version from .mise.toml. Otherwise grab Zig 0.16.0 manually.
|
|
zig build
|
|
# Binary lands at zig-out/bin/zfin
|
|
```
|
|
|
|
### Configure
|
|
|
|
```bash
|
|
# Set at least one API key plus your contact email (see "API keys" below).
|
|
# The email is required for ETF profiles + `enrich` because SEC EDGAR mandates
|
|
# a User-Agent contact.
|
|
export TIINGO_API_KEY=your_key
|
|
export ZFIN_USER_EMAIL=you@example.com
|
|
```
|
|
|
|
### Use it
|
|
|
|
```bash
|
|
zfin perf VTI # trailing returns
|
|
zfin quote AAPL # real-time quote
|
|
zfin options AAPL # options chains
|
|
zfin earnings MSFT # earnings history
|
|
zfin portfolio # portfolio summary (reads portfolio.srf)
|
|
zfin analysis # portfolio analysis (reads portfolio.srf + metadata.srf)
|
|
|
|
# Interactive TUI
|
|
zfin i # auto-loads portfolio.srf from cwd
|
|
zfin i -p portfolio.srf -w watchlist.srf
|
|
zfin i -s AAPL # start with a symbol, no portfolio
|
|
```
|
|
|
|
Building from source requires Zig 0.16.0.
|
|
|
|
## Documentation
|
|
|
|
Full user documentation lives in [`docs/`](docs/README.md) and is built
|
|
around the runnable example portfolios in [`examples/`](examples/).
|
|
|
|
- **New here?** [Getting started](docs/getting-started.md) -- install,
|
|
configure, and run your first commands.
|
|
- **Learn the model:** [Core concepts](docs/explanation/concepts.md).
|
|
- **Do a task (the user manual):**
|
|
- [Build your portfolio](docs/guides/set-up-your-portfolio.md)
|
|
- [Classify your holdings](docs/guides/classify-holdings.md) and [map your accounts](docs/guides/set-up-accounts.md)
|
|
- [Read your portfolio](docs/guides/read-your-portfolio.md)
|
|
- [Plan for retirement](docs/guides/plan-retirement.md)
|
|
- [Snapshots and history](docs/guides/snapshots-and-history.md), [track contributions](docs/guides/track-contributions.md)
|
|
- [Audit against your brokerage](docs/guides/audit-against-brokerage.md)
|
|
- [Customize the TUI](docs/guides/customize-the-tui.md), [offline use and refreshing data](docs/guides/offline-and-refresh.md)
|
|
- **Look something up (reference):**
|
|
- [CLI commands](docs/reference/cli/index.md)
|
|
- Config files: [`portfolio.srf`](docs/reference/config/portfolio-srf.md), [`accounts.srf`](docs/reference/config/accounts-srf.md), [`metadata.srf`](docs/reference/config/metadata-srf.md), [`projections.srf`](docs/reference/config/projections-srf.md), and [more](docs/reference/config/environment.md)
|
|
- [The interactive TUI](docs/reference/tui.md)
|
|
- [Data providers and API keys](docs/reference/providers.md)
|
|
- **Understand the why (explanation):** [caching](docs/explanation/caching.md), [data providers](docs/explanation/data-providers.md), [returns](docs/explanation/returns-and-performance.md), [the projection model](docs/explanation/projections-model.md), [FAQ](docs/explanation/faq-troubleshooting.md).
|
|
|
|
## Data providers
|
|
|
|
zfin aggregates data from multiple free-tier APIs, using each for what
|
|
it does best, with aggressive caching to stay within free-tier limits.
|
|
|
|
| Data type | Provider | Auth | Free-tier limit | Cache TTL |
|
|
|-----------------------|------------------|----------------------|----------------------------|--------------|
|
|
| Daily candles (OHLCV) | Tiingo | `TIINGO_API_KEY` | 1,000 req/day, 50 req/hour | 23h45m |
|
|
| Real-time quotes | Yahoo Finance | None required | Unofficial | Never cached |
|
|
| Quote fallback | TwelveData | `TWELVEDATA_API_KEY` | 8 req/min, 800/day | Never cached |
|
|
| Dividends | Polygon | `POLYGON_API_KEY` | 5 req/min | 14 days |
|
|
| Splits | Polygon | `POLYGON_API_KEY` | 5 req/min | 14 days |
|
|
| Options chains | CBOE | None required | ~30 req/min (self-imposed) | 1 hour |
|
|
| Earnings | FMP | `FMP_API_KEY` | 250 req/day | 30 days* |
|
|
| ETF profiles | SEC EDGAR | `ZFIN_USER_EMAIL` | 10 req/sec | ~90 days |
|
|
| Classification | Wikidata + EDGAR | `ZFIN_USER_EMAIL` | No per-day quota | Long-lived |
|
|
|
|
Not all keys are required; without a given key, that data type is
|
|
simply unavailable. For per-provider notes, signup links, the full
|
|
caching/TTL model, and the complete environment-variable list, see
|
|
[Data providers and API keys](docs/reference/providers.md),
|
|
[Caching and data freshness](docs/explanation/caching.md), and
|
|
[Environment variables](docs/reference/config/environment.md).
|
|
|
|
## Architecture
|
|
|
|
```
|
|
src/
|
|
root.zig Library root, exports all public types
|
|
format.zig Shared formatters, braille engine, ANSI helpers
|
|
config.zig Configuration from env vars / .env files
|
|
service.zig DataService: cache-check -> fetch -> cache -> return
|
|
models/
|
|
candle.zig OHLCV price bars
|
|
date.zig Date type with arithmetic, snapping, formatting
|
|
dividend.zig Dividend records with type classification
|
|
split.zig Stock splits
|
|
option.zig Option contracts and chains
|
|
earnings.zig Earnings events with surprise calculation
|
|
etf_profile.zig ETF profiles with holdings and sectors
|
|
portfolio.zig Lots, positions, and portfolio aggregation
|
|
classification.zig Classification metadata parser
|
|
quote.zig Real-time quote data
|
|
providers/
|
|
tiingo.zig Tiingo: daily candles (primary), supplementary div/split merge
|
|
twelvedata.zig TwelveData: quote fallback
|
|
polygon.zig Polygon: dividends, splits (primary, with forward-looking entries)
|
|
fmp.zig FMP: earnings (actuals + estimates)
|
|
cboe.zig CBOE: options chains (no API key)
|
|
Edgar.zig SEC EDGAR: ETF profiles (NPORT-P), mutual-fund ticker map, XBRL company facts
|
|
Wikidata.zig Wikidata SPARQL: classification metadata for `enrich`
|
|
yahoo.zig Yahoo Finance: quotes (primary), candles (Tiingo fallback)
|
|
openfigi.zig OpenFIGI: CUSIP to ticker lookup
|
|
xml.zig Vendored XML parser used by Edgar.zig (see "Vendored code")
|
|
analytics/
|
|
indicators.zig SMA, Bollinger Bands, RSI
|
|
performance.zig Trailing returns (as-of-date + month-end)
|
|
risk.zig Volatility, Sharpe, drawdown
|
|
valuation.zig Portfolio summary, allocations, covered call adjustments
|
|
analysis.zig Portfolio analysis engine (breakdowns by class/sector/geo/account/tax)
|
|
cache/
|
|
store.zig SRF file cache with TTL freshness checks
|
|
net/
|
|
http.zig HTTP client with retries and server error retry
|
|
rate_limiter.zig Token-bucket rate limiter
|
|
commands/
|
|
common.zig Shared CLI helpers (progress, formatting)
|
|
perf.zig Trailing returns command
|
|
quote.zig Quote command
|
|
... (14 command files)
|
|
tui.zig Interactive TUI application
|
|
tui/
|
|
chart.zig z2d pixel chart renderer (Kitty graphics)
|
|
keybinds.zig Configurable keybinding system
|
|
theme.zig Configurable color theme
|
|
```
|
|
|
|
Data files (user-managed, in project root):
|
|
```
|
|
portfolio.srf Portfolio lots
|
|
metadata.srf Classification metadata for analysis
|
|
accounts.srf Account to tax type mapping for analysis
|
|
```
|
|
|
|
### Dependencies
|
|
|
|
| Dependency | Source | Purpose |
|
|
|----------------------------------------------------|---------------|---------------------------------------------------|
|
|
| [SRF](https://git.lerch.org/lobo/srf) | Git | Cache file format and portfolio/watchlist parsing |
|
|
| [libvaxis](https://github.com/rockorager/libvaxis) | Git (v0.6.0) | Terminal UI rendering |
|
|
| [z2d](https://github.com/vancluever/z2d) | Git (v0.11.0) | Pixel chart rendering (Kitty graphics protocol) |
|
|
|
|
## Building
|
|
|
|
Requires Zig 0.16.0. The canonical version is pinned in `.mise.toml`:
|
|
|
|
```bash
|
|
# Recommended: use mise to install the right Zig and ZLS automatically
|
|
mise install
|
|
|
|
# Or, with Zig 0.16.0 already on PATH:
|
|
zig build # build the zfin binary
|
|
zig build test # run all tests
|
|
zig build run -- <args> # build and run
|
|
```
|
|
|
|
The compiled binary is at `zig-out/bin/zfin`.
|
|
|
|
## Vendored code
|
|
|
|
A small amount of third-party source is vendored directly into the
|
|
tree (rather than added as a Zig package dependency) where the
|
|
upstream is small, stable, and not packaged for `build.zig.zon`:
|
|
|
|
| File | Source | Purpose |
|
|
|-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------|
|
|
| `src/providers/xml.zig` | [Snektron/vulkan-zig](https://github.com/Snektron/vulkan-zig/blob/797ae8af88e84753af9640266de61a985b76b580/generator/xml.zig), via [aws-zig](https://github.com/elerch/aws-sdk-for-zig) | XML DOM parser used by the EDGAR provider for NPORT-P primary documents. |
|
|
|
|
Each vendored file carries a `// VENDORED - see README.md` header
|
|
identifying its upstream source. When updating, copy the new
|
|
upstream verbatim and re-add the header.
|
|
|
|
## License
|
|
|
|
MIT
|