Adds a ~36s screen recording of the Streamlit dashboard (portfolio & option positions, per-persona overnight theses, AI Investment Committee verdicts, orders, agent roster) as docs/demo.mp4, with an inline GIF teaser at the top of the README linking to the full MP4. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
102 lines
5.9 KiB
Markdown
102 lines
5.9 KiB
Markdown
# Overnight Local-LLM Paper-Trading Agent
|
||
|
||
<p align="center">
|
||
<a href="docs/demo.mp4"><img src="docs/demo.gif" alt="Dashboard tour: portfolio, agent theses, AI committee verdicts, orders" width="820"></a>
|
||
<br>
|
||
<em>▶ Dashboard tour — portfolio & option positions, each persona's overnight theses, the AI Investment Committee verdicts, and the orders that got placed. <a href="docs/demo.mp4">Click for the full-quality MP4 (with sound).</a></em>
|
||
</p>
|
||
|
||
Every night the Mac wakes itself, runs **4 trader personas** one at a time against **one local LLM**
|
||
(gpt-oss-20b via [oMLX](https://omlx.ai), an Apple-MLX inference server). Each persona researches the
|
||
web + live market data, forms up to **4 trade theses — at least one of them an options trade** —
|
||
and writes JSON. In the morning at market open a separate job reads that JSON and places
|
||
**Alpaca paper trades** with programmatic risk guardrails. Everything is visible in a local
|
||
Streamlit dashboard, including an **Agents tab** that manages the roster (add/edit/disable agents,
|
||
per-agent research budgets) via `state/agents.json` — no code edits needed.
|
||
|
||
> **Paper trading only.** Fake money, real prices. "The build works" ≠ "it's profitable" — the
|
||
> quality of a local model's theses is the open question you tune over time.
|
||
|
||
## Requirements
|
||
- Apple Silicon Mac (built/tested on M4 Pro, 24 GB), **plugged in, lid open, logged in** overnight.
|
||
- [oMLX](https://omlx.ai) (Apple-MLX server) auto-running on `:8090` with a model downloaded
|
||
(default `gpt-oss-20b`; toggle `qwen35_27b`). Enforces an API key, auto-read from `~/.omlx/settings.json`.
|
||
- [uv](https://docs.astral.sh/uv/) for Python env management.
|
||
- Alpaca **paper** account + Finnhub free key.
|
||
|
||
## Setup
|
||
```bash
|
||
# 1. Python env + deps
|
||
uv sync
|
||
|
||
# 2. Secrets
|
||
cp .env.example .env # then paste your Alpaca paper + Finnhub keys
|
||
|
||
# 3. Model host — oMLX auto-starts on login; if not, bring it up + verify tool-calling
|
||
omlx start # OpenAI-compatible API on http://127.0.0.1:8090
|
||
uv run python scripts/smoke_toolcalling.py # GATE: multi-turn tool calls must PASS
|
||
|
||
# 4. Phase-0 gate
|
||
uv run pytest
|
||
```
|
||
|
||
Switch models any time with one line in `.env`: `MODEL_PROFILE=gpt_oss` or `qwen35_27b`.
|
||
|
||
## Entry points
|
||
| Command | What it does |
|
||
|---|---|
|
||
| `uv run python -m orchestration.run_nightly` | Nightly research run (all enabled agents → JSON). `--compressed` for a fast test |
|
||
| `uv run python -m execution.run_market_open` | Morning: JSON → guardrails → Alpaca paper orders. `--force` to test while closed |
|
||
| `uv run streamlit run web/dashboard.py` | Dashboard: positions, PnL, theses, orders, logs |
|
||
| `uv run python -m reporting.report` | CLI summary |
|
||
|
||
## How it works
|
||
`run_nightly` starts oMLX, then runs Nova → Warren-lite → Atlas → Maverick **sequentially** (one
|
||
model, time-sliced with rollover budgets; per-agent budgets are dashboard-editable). The roster
|
||
comes from `config/agent_registry.py` (built-ins merged with `state/agents.json`). Each agent
|
||
researches with tools (`run_python` for math, `run_analysis` for data/charts, web search/fetch,
|
||
Alpaca/Finnhub/yfinance market data, options chains, `get_portfolio` for continuity) and its
|
||
output is checkpointed incrementally to `state/output/<date>/`. Nudges keep agents researching
|
||
broadly, steer them to the **options mandate** (each night's picks must include a researched
|
||
single-leg option), and converge them near the end of their budget.
|
||
|
||
**Each persona trades its own Alpaca paper account** (Nova→agent1, Warren-lite→agent2,
|
||
Atlas→agent3, Maverick→agent4 — Maverick is the deliberately aggressive options/shorts book),
|
||
so the books — and their PnL — stay separate and comparable. `run_market_open` gates on
|
||
Alpaca's clock, then per account applies `execution/guardrails.py` (position/day caps, sizing,
|
||
buying-power, an options conviction floor + premium cap, and a reserved slot so the mandated
|
||
option trade isn't trimmed) and places **GTC bracket** orders (marketable-limit entry so
|
||
stop/take legs survive multi-day holds).
|
||
|
||
> **Adding an agent:** use the dashboard's 🤖 Agents tab (clone a template, tweak knobs), create
|
||
> a fresh Alpaca paper account for it, enable **options trading (level 2)** on that account, and
|
||
> add `ALPACA_<ID>_KEY` / `ALPACA_<ID>_SECRET` to `.env`. Maverick ships built-in but still needs
|
||
> its own account keys the same way.
|
||
|
||
### The differentiating layer
|
||
- **Market regime snapshot** — SPY trend / VIX / sector momentum computed in code each night and
|
||
injected into every agent's kickoff (shared ground truth).
|
||
- **Self-learning journal** — each agent sees its own past picks marked-to-market before
|
||
researching; losses and wins become explicit lessons.
|
||
- **AI Investment Committee** — a Chief-Risk-Officer LLM pass reviews the whole book after
|
||
research and issues per-pick verdicts (APPROVE / REDUCE / VETO with reasons). The memo lands in
|
||
the Reports tab and the morning executor **enforces** the verdicts.
|
||
|
||
## Automate it (America/Chicago)
|
||
- **00:00–07:00** research (fair-share time-slicing: ~105 min/agent with 4 agents; tune
|
||
per-agent budgets from the dashboard), machine woken at **23:55**.
|
||
- **08:30** execution (= 09:30 ET open; gated on Alpaca's clock, never local time).
|
||
|
||
```bash
|
||
scripts/install_launchd.sh # loads the 3 launchd jobs
|
||
sudo pmset repeat wakeorpoweron MTWRFSU 23:55:00 # one-time: wake the Mac nightly (needs sudo)
|
||
```
|
||
Overnight requirements: **plugged in, lid open, logged in** (lock screen OK), oMLX running, `.env` filled.
|
||
Remove with `scripts/uninstall_launchd.sh` + `sudo pmset repeat cancel`.
|
||
|
||
## Instruments & safety
|
||
- Trades **stocks (long or short)** and **single-leg long options** (buy calls/puts). Per-trade
|
||
+ per-day caps; stops/takes enforced in code, not trusted from the LLM. Shorts use inverted
|
||
brackets; options are sized by premium×100 (max loss = premium; see `docs/options-phase.md`).
|
||
- `run_python` executes model-generated code locally — kept math-only, sandboxed, no network.
|