Add dynamic agent registry and options mandate
Introduces a dashboard-managed agent registry (`state/agents.json`) used by nightly research and market-open execution, including support for custom/disabled agents and per-agent time budgets. Expands personas to four agents (adds Maverick), shifts pick targets to include mandatory options, and updates prompts/finalization nudges to enforce option research without hard-failing runs. Strengthens execution safety by adding option-specific guardrails (conviction floor, premium cap, reserved option slot through trade/day/buying-power caps), validates OCC option symbols in schemas, and normalizes invalid option direction cases. The dashboard was refactored into modular views, adds an Agents admin tab, and improves live portfolio visibility with Alpaca-first data and snapshot fallback.
This commit is contained in:
1 parent
b3821abd69
commit
e1ac514f30
36 files changed
+1476
-294
No files matched your search
@@ -1,11 +1,12 @@
|
||||
# Overnight Local-LLM Paper-Trading Agent
|
||||
|
||||
Every night the Mac wakes itself, runs **3 trader personas** one at a time against **one local LLM**
|
||||
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 a stock thesis, and writes JSON. In the morning at market open a
|
||||
separate job reads that JSON and places
|
||||
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.
|
||||
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.
|
||||
@@ -38,23 +39,33 @@ Switch models any time with one line in `.env`: `MODEL_PROFILE=gpt_oss` or `qwen
|
||||
## Entry points
|
||||
| Command | What it does |
|
||||
|---|---|
|
||||
| `uv run python -m orchestration.run_nightly` | Nightly research run (3 personas → JSON). `--compressed` for a fast test |
|
||||
| `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 **sequentially** (one model,
|
||||
time-sliced with rollover budgets). Each agent researches with tools (`run_python` for all math,
|
||||
web search/fetch, Alpaca/Finnhub/yfinance market data, `get_portfolio` for continuity) and its
|
||||
output is checkpointed incrementally to `state/output/<date>/`. A min-steps nudge keeps agents
|
||||
researching broadly instead of stopping early.
|
||||
`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),
|
||||
so the three books — and their PnL — stay separate and comparable. `run_market_open` gates on
|
||||
**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) and places **GTC bracket** orders (marketable-limit entry so stop/take legs survive
|
||||
multi-day holds).
|
||||
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
|
||||
@@ -66,7 +77,8 @@ multi-day holds).
|
||||
the Reports tab and the morning executor **enforces** the verdicts.
|
||||
|
||||
## Automate it (America/Chicago)
|
||||
- **00:00–07:00** research (~2.3 hr/agent), machine woken at **23:55**.
|
||||
- **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
|
||||
|
||||
Reference in new issue
Block a user