finance library and cli/tui
Find a file
2026-06-23 09:29:37 -07:00
.forgejo/workflows initial attempt - macos build/publish 2026-05-30 10:49:49 -07:00
build upgrade to zig 0.16.0 2026-05-09 22:40:33 -07:00
docker create docker image 2026-04-18 12:41:22 -07:00
docs add acknowledgements to docs 2026-06-23 09:29:37 -07:00
examples adding previously ignored example files 2026-05-13 11:15:04 -07:00
src add doctor command 2026-06-20 16:53:01 -07:00
.gitignore user-errors management...any non-user error panics like before 2026-05-19 12:28:05 -07:00
.mise.toml update mise config for use on risc-v 2026-06-19 09:45:36 -07:00
.pre-commit-config.yaml delint/get basic async checks working 2026-06-11 20:41:21 -07:00
AGENTS.md add new review command/tab 2026-06-05 13:16:25 -07:00
build.zig upgrade to zig 0.16.0 2026-05-09 22:40:33 -07:00
build.zig.zon update srf/wire edgar and wikidata into service 2026-05-29 12:23:43 -07:00
LICENSE ai generated, functional, no code review yet 2026-02-25 14:10:27 -08:00
metadata.srf add international etfs to metadata 2026-04-09 17:04:00 -07:00
README.md add docs/guides 2026-06-22 14:53:53 -07:00
TODO.md add docs/guides 2026-06-22 14:53:53 -07:00

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

# 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

# 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

# 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

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/ and is built around the runnable example portfolios in examples/.

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, Caching and data freshness, and Environment variables.

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 Git Cache file format and portfolio/watchlist parsing
libvaxis Git (v0.6.0) Terminal UI rendering
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:

# 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, via aws-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