2026-09-11 09:54:49 +08:00
2026-09-11 09:54:49 +08:00
2026-09-11 09:54:49 +08:00
2026-09-11 09:54:49 +08:00
2026-09-05 09:55:24 +08:00
2026-09-05 09:55:24 +08:00
2026-09-05 22:35:23 +08:00
2026-09-05 10:25:39 +08:00
2026-09-05 09:55:24 +08:00
2026-09-05 22:35:23 +08:00
2026-09-05 09:55:24 +08:00
2026-09-05 22:35:23 +08:00
2026-09-05 09:55:24 +08:00

stonks

Daily financial news + market data analysis. Fetches crypto/equity/futures prices (yfinance-equivalent + Finnhub) and market news (RSS), asks Claude for an investment-advice briefing, and posts it to Discord — on a systemd user timer.

See PLAN.md for the full design, cost analysis, and rationale.

Build

make build

Configure

mkdir -p ~/.config/stonks
cp config/config.yaml ~/.config/stonks/config.yaml
cp config/secrets.env.example ~/.config/stonks/secrets.env
chmod 600 ~/.config/stonks/secrets.env
$EDITOR ~/.config/stonks/secrets.env   # fill in FINNHUB_API_KEY, DISCORD_WEBHOOK_URL, (ANTHROPIC_API_KEY if using api mode)

If analyzer.mode: subscription (the default), install Claude Code and authenticate once:

claude login

Multi-agent mode (optional)

analyzer.advisors in config.yaml lists additional CLI-based AI analysts (Gemini, Codex) that get the same fetched data and produce an independent take; their output is appended to Claude's prompt as extra context (Claude still writes the one final report — see PLAN.md § "Claude integration"). Each needs to be installed and logged in separately:

gemini    # first run walks through auth
codex login

A failing or unauthenticated advisor is logged as a warning and simply excluded — it never fails the run. Remove an entry (or the whole advisors: list) to disable multi-agent mode.

Archiving runs

Every run saves its fetched data, full prompt (including any advisor section), raw and parsed analysis to archive.dir (default ~/.local/state/stonks/runs), one timestamped subdirectory per run: fetched.json, prompt.txt, analysis_raw.md, report.md, recommendations.json. This is always on — besides being useful for debugging prompt or parsing issues, the next run reads back report.md from the most recent subdirectory so it can avoid repeating unchanged commentary from ~5 hours ago. These accumulate over time with no automatic cleanup.

Install as a user-scope systemd service

mkdir -p ~/.config/systemd/user
make install   # builds and installs to ~/.local/bin/stonks
cp systemd/stonks.service systemd/stonks.timer ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now stonks.timer
loginctl enable-linger "$USER"   # keep the timer firing while logged out

Run it once manually to verify before waiting for the timer:

systemctl --user start stonks.service
journalctl --user -u stonks.service -f

Adding a new fetcher / output

Implement the fetch.Fetcher / output.Output interface in a new file under internal/fetch / internal/output, self-register it in an init() (see internal/fetch/rss.go for an example), add the name to config.yaml, and rebuild. See PLAN.md § "Modularity in Go" for why this is compile-time rather than a runtime plugin system.

S
Description
No description provided
Readme
185 KiB
0 Stars 2 Watchers 0 Forks
Languages
Go 99.6%
Makefile 0.4%