2 ms·
Trader – LLM agent for Robinhood with a Rust safety layer and paper trading
- zhangxd6 4mo agoI built this after Robinhood launched their official agentic trading MCP server. The idea: give an LLM access to the Robinhood MCP tools (portfolio, quotes, order placement), but sit a typed Rust safety layer in the middle that hard-enforces risk limits regardless of what the model decides. The architecture is a ToolExecutor trait chain: LLM → SafetyValidator → ResearchExecutor → SimulationExecutor → Robinhood MCP Each layer is independent. The SafetyValidator checks every order against your config (stop-loss, position caps, per-trade USD cap, daily trade count, minimum cash reserve) and rejects violations before they reach the broker. The ResearchExecutor intercepts web_search and get_stock_news calls and satisfies them locally via Yahoo Finance RSS and Brave/DDG — no extra API key required for the news side. A new get_stock_fundamentals tool fetches the real 52-week high, volume ratio, and P/E from Yahoo Finance so the LLM evaluates buy filters on actual data instead of guessing. Strategy is defined in YAML as a hybrid: structured thresholds enforced by Rust plus free-text judgment rules passed verbatim to the LLM prompt. You can run multiple strategies in parallel, each on its own interval. Paper trading uses live Robinhood market data against a virtual portfolio persisted to disk, with an equity curve you can view as an ASCII chart in the TUI or export to CSV. The audit log writes one JSONL line per cycle with the full turn-by-turn conversation — system prompt, every tool call and result, intermediate LLM reasoning, final response — so you can replay and inspect exactly what the model was thinking. Works with any OpenAI-compatible endpoint. I've tested with GPT-4o, Claude, Groq's llama-3.3-70b (free tier), and locally with Ollama qwen2.5:7b. The 7B local model is borderline for reliable tool calling; 14B+ is more consistent. The obvious caveat: this is paper-trading software that happens to also support live mode. I wouldn't run it live without significant time in simulation first. dry_run: true is the default and the safety layer still enforces everything in dry-run mode — it just blocks the final order from reaching Robinhood.