Back to projects
Autonomous Trading

Trader Joe

Judgment, Oversight & Execution

A five-role AI team that independently analyzes pre-market news, manages a core-satellite portfolio on Alpaca, and self-reviews every evening against the SPY benchmark. Runs 24/7 on a Synology NAS.

Share this case study →
5
Domain experts
ReAct over domain experts
Orchestration
3
LLM families
The hard part

The hard part: hard risk limits enforced in code the model can't override, and a self-improving loop where a repeated mistake gets promoted from a logged lesson into a permanent, hard-coded gate.

Architecture at a glance
In production
As of 2026-07-14
ReAct orchestrator over domain expertsConfig-driven LLM & agent configExternalized prompt storeVersioned reasoning-trace storeA2A protocol peer (portfolio_summary, watchlist, investment_consult)Direct/A2A provider parity verification before cutoverCommand-center portfolio-summary bridge for Wall Street
Complete internal roster
Hands off toHands off toHands off toCan vetoorchestratormarket_analysisstrategy_timingrisk_sizingexecutionreview
Agents

APScheduler-based; wakes each expert on a market-driven schedule

TraderJoe in the ecosystem
Stack

Python, Postgres, Alpaca, Claude, DeepSeek, Qwen

01Five agents, one schedule

An APScheduler-based orchestrator wakes each agent on a market-driven schedule. The Analyst runs at 08:30 ET on DeepSeek V4 Pro — heavy reasoning, once daily — reading overnight news, the macro calendar, and its own historical lessons before writing a pre-market brief. The Trader runs every 20 minutes from 09:10 to 15:50 ET on DeepSeek V4 Flash — lightweight, about 21 calls a day — deciding which tickers to open or close, at what size, with what stop. Before any consequential open, a Challenger role reviews the same setup on Claude Opus — deliberately the opposite model family from the Trader's DeepSeek, because a same-family second opinion tends to agree with itself for the same reasons it was wrong the first time. The Challenger can veto the trade; if it's unreachable, it fails open rather than freezing the desk. The Evaluator runs at midday on DeepSeek V4 Pro, re-examining every open position against its original thesis. The Reviewer runs at market close and drives the self-improvement loop below. Only the Trader can actually place an order.

02Pure function core, imperative shell

Every trading decision function is pure — zero I/O, zero side effects, fully unit-testable. The 52-week-high momentum signal (citing George & Hwang 2004) always returns every diagnostic field, even for candidates that fail, so nothing is ever a black-box rejection. The core-sleeve rebalancer is pure too: no I/O, no LLM, just a list of orders for a thin wrapper to execute. The practical effect: roughly 90% of the trading logic is unit-tested without a live broker connection, without mocking, and without any risk of an accidental real order during a test run.

03The gates the LLM can't argue its way past

The Trader has the richest toolset of the five agents, but several deterministic gates constrain it regardless of what the model decides. A cooldown system prevents re-proposing the same ticker on consecutive ticks — 120 minutes after actually opening a position, 40 minutes after evaluating one without acting, and cooldowns only ever extend, never shorten. An exit manager assigns every closed position a standardized reason and flags anything held beyond 48 hours as overdue — a pure implementation of the Triple Barrier Method's vertical barrier. Above both sits a daily circuit breaker: if the portfolio drops 2% or more in a session, new entries halt outright for the rest of the day, no override. And if the Analyst's morning brief is ever missing or stale, the Trader hard-blocks new opens rather than trading blind — a safety default, not a suggestion it can reason its way around.

04Core-satellite: two agents, one portfolio

The portfolio is split into two mechanically separate sleeves. The Core sleeve (SPY/QQQ/VOO, 60% allocation) runs zero-LLM drift-band rebalancing — pure math, an order only when drift exceeds 8%. The Satellite sleeve (Active, 40%) is fully LLM-driven, deciding every 20 minutes via DeepSeek V4 Flash. This guarantees that even if the satellite agent's reasoning goes completely off track, 60% of the portfolio is untouched and still tracking the market. Capital preservation is architected in, not just a policy.

05When a lesson becomes a law

Every trading day ends with the Reviewer computing P&L attribution, looking for patterns across trades, and writing dated, ID-tagged lessons into a journal file — committed and pushed to Gitea, no vector database or RAG pipeline involved; the git history is the memory system. Most lessons just inform the next morning's brief. But when the same mistake shows up on repeat, it graduates: after several logged instances of opening positions below the 20-day moving average and losing, that threshold stopped being a note to remember and became a hard-coded check in the risk module — closing the loop from 'we noticed this went wrong' to 'the code no longer allows it.'

Stack

Python, Claude API, DeepSeek API, Alpaca, Finnhub, EDGAR, pgvector, APScheduler, Docker, Gitea Actions CI/CD (self-hosted).

— Résumé & Contact

Let's talk.

LinkedIn ↗[email protected]