zfin/TODO.md
Emil Lerch 36d096a938
All checks were successful
Generic zig build / build (push) Successful in 53s
enable ^L to repaint
2026-03-17 09:50:46 -07:00

111 lines
4.4 KiB
Markdown

# Future Work
## Human review of analytics modules
All analytics modules have been human-reviewed:
- `src/analytics/valuation.zig` — reviewed
- `src/analytics/risk.zig` — reviewed (rewritten: monthly returns, per-period Sharpe, historical T-bill rates)
- `src/analytics/performance.zig` — reviewed
- `src/analytics/analysis.zig` — reviewed
- `src/analytics/indicators.zig` — AI-reviewed only; human review deferred (lower priority)
## Provider review
- `src/providers/tiingo.zig` — reviewed (new: primary candle provider)
- `src/providers/yahoo.zig` — needs human review
- All other providers — reviewed
## CLI/TUI changes
Risk metrics (Sharpe, volatility, max drawdown) now display per trailing period
(1Y, 3Y, 5Y, 10Y) in both the TUI performance tab and CLI `perf` command.
CLI `portfolio` command shows 3-year risk metrics per symbol.
Performance comparison feature idea: compare risk/return metrics of two or more
securities side by side. Scope TBD — could focus on stocks/ETFs only. Open
question: fixed at 2, or arbitrary N?
## TUI issues
Starting the TUI with a ticker symbol doesn't uppercase (why can't we just solve
this once?). Display artifacts that don't go away when switching tabs (need
specific steps to reproduce).
## Risk-free rate maintenance
T-bill rates are hardcoded in `src/analytics/risk.zig` as a year-by-year table
(source: FRED series DTB3). Each trailing period uses the average rate over its
date range. The table includes update instructions as doc comments.
**Action needed annually:** Update the current year's rate mid-year, finalize
the prior year's rate in January. See the curl commands in the `tbill_rates`
doc comment.
## CLI/TUI code review (lower priority)
No review has been done on these files. They are presentation-layer code
and not part of the reusable library API.
TUI:
- `src/tui.zig`
- `src/tui/chart.zig`
- `src/tui/keybinds.zig`
- `src/tui/theme.zig`
Commands:
- `src/commands/common.zig`
- `src/commands/analysis.zig`
- `src/commands/cache.zig`
- `src/commands/divs.zig`
- `src/commands/earnings.zig`
- `src/commands/enrich.zig`
- `src/commands/etf.zig`
- `src/commands/history.zig`
- `src/commands/lookup.zig`
- `src/commands/options.zig`
- `src/commands/perf.zig`
- `src/commands/portfolio.zig`
- `src/commands/quote.zig`
- `src/commands/splits.zig`
## Market-aware cache TTL for daily candles
Daily candle TTL is currently 23h45m, but candle data only becomes meaningful
after the market close. Investigate keying the cache freshness to ~4:30 PM
Eastern rather than a rolling window. This would avoid unnecessary refetches
during the trading day and ensure a fetch shortly after close gets fresh data.
Probably alleviated by the cron job approach.
## Cron timing for mutual fund NAVs
Tiingo publishes mutual fund NAVs after midnight ET. The server cron (currently
8 PM ET weekdays) gets stock/ETF data same-day but mutual fund NAVs lag by one
trading day. Consider pushing the cron to midnight ET or adding a second morning
run for funds.
## On-demand server-side fetch for new symbols
Currently the server's SRF endpoints (`/candles`, `/dividends`, etc.) are pure
cache reads — they 404 if the data isn't already on disk. New symbols only get
populated when added to the portfolio and picked up by the next cron refresh.
Consider: on a cache miss, instead of blocking the HTTP response with a
multi-second provider fetch, kick off an async background fetch (or just
auto-add the symbol to the portfolio) and return 404 as usual. The next
request — or the next cron run — would then have the data. This gives
"instant-ish gratification" for new symbols without the downsides of
synchronous fetch-on-miss (latency, rate limit contention, unbounded cache
growth from arbitrary tickers).
Note that this process doesn't do anything to eliminate all the API keys
that are necessary for a fully functioning system. A more aggressive view
would be to treat ZFIN_SERVER as a 100% source of record, but that would
introduce some opacity to the process as we wait for candles (for example) to
populate. This could be solved on the server by spawning a thread to fetch the
data, then returning 202 Accepted, which could then be polled client side. Maybe
this is a better long term approach?
## Server deployment
After committing and pushing changes, rebuild and deploy zfin-server on nas2.
The server needs the `TIINGO_API_KEY` added to `/data/zfin/.env` on the host.