Compare commits

...

4 commits

Author SHA1 Message Date
51c7dc9fdd
remove perf comparison ideal from TODO
Some checks failed
Generic zig build / build (push) Failing after 13s
2026-03-17 10:20:31 -07:00
e93d24c6d7
update todo.md 2026-03-17 10:12:54 -07:00
e5cb7d2b32
uppercase the command line symbol name 2026-03-17 10:10:29 -07:00
b248461034
update todo.md 2026-03-17 10:07:37 -07:00
2 changed files with 9 additions and 42 deletions

42
TODO.md
View file

@ -1,35 +1,9 @@
# Future Work # 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 ## TUI issues
Starting the TUI with a ticker symbol doesn't uppercase (why can't we just solve Display artifacts that don't go away when switching tabs (need specific steps
this once?). Display artifacts that don't go away when switching tabs (need to reproduce). Lower priority now that ^L has been introduced to re-paint
specific steps to reproduce).
## Risk-free rate maintenance ## Risk-free rate maintenance
@ -76,13 +50,6 @@ 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. during the trading day and ensure a fetch shortly after close gets fresh data.
Probably alleviated by the cron job approach. 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 ## On-demand server-side fetch for new symbols
Currently the server's SRF endpoints (`/candles`, `/dividends`, etc.) are pure Currently the server's SRF endpoints (`/candles`, `/dividends`, etc.) are pure
@ -104,8 +71,3 @@ 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 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 data, then returning 202 Accepted, which could then be polled client side. Maybe
this is a better long term approach? 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.

View file

@ -3630,6 +3630,7 @@ pub fn run(allocator: std.mem.Allocator, config: zfin.Config, args: []const []co
var portfolio_path: ?[]const u8 = null; var portfolio_path: ?[]const u8 = null;
var watchlist_path: ?[]const u8 = null; var watchlist_path: ?[]const u8 = null;
var symbol: []const u8 = ""; var symbol: []const u8 = "";
var symbol_upper_buf: [32]u8 = undefined;
var has_explicit_symbol = false; var has_explicit_symbol = false;
var skip_watchlist = false; var skip_watchlist = false;
var chart_config: chart_mod.ChartConfig = .{}; var chart_config: chart_mod.ChartConfig = .{};
@ -3656,7 +3657,9 @@ pub fn run(allocator: std.mem.Allocator, config: zfin.Config, args: []const []co
} else if (std.mem.eql(u8, args[i], "--symbol") or std.mem.eql(u8, args[i], "-s")) { } else if (std.mem.eql(u8, args[i], "--symbol") or std.mem.eql(u8, args[i], "-s")) {
if (i + 1 < args.len) { if (i + 1 < args.len) {
i += 1; i += 1;
symbol = args[i]; const len = @min(args[i].len, symbol_upper_buf.len);
_ = std.ascii.upperString(symbol_upper_buf[0..len], args[i][0..len]);
symbol = symbol_upper_buf[0..len];
has_explicit_symbol = true; has_explicit_symbol = true;
skip_watchlist = true; skip_watchlist = true;
} }
@ -3668,7 +3671,9 @@ pub fn run(allocator: std.mem.Allocator, config: zfin.Config, args: []const []co
} }
} }
} else if (args[i].len > 0 and args[i][0] != '-') { } else if (args[i].len > 0 and args[i][0] != '-') {
symbol = args[i]; const len = @min(args[i].len, symbol_upper_buf.len);
_ = std.ascii.upperString(symbol_upper_buf[0..len], args[i][0..len]);
symbol = symbol_upper_buf[0..len];
has_explicit_symbol = true; has_explicit_symbol = true;
} }
} }