Skip to content
Thrivbe
← All experiments
In progressStarted July 1, 2026Updated August 2, 2026

Can a sealed agent fleet trade unsupervised — on paper?

Paper-Trading Agent Fleet

  • Python (stdlib only)
  • Alpaca paper API
  • LLM sentiment scoring
  • Kronos-base time-series model
  • Codex (headless, sandboxed)
  • NautilusTrader
  • SQLite
  • systemd timers

Relevant services: AI Digital Teammates · Second Brain Audit — €750 · Thrivbe AI

Hypothesis

Trading is the harshest testbed for autonomous agents: adversarial, numeric, unforgiving of bugs. Run many strategies simultaneously in a paper-money arena with honest attribution, and let the data — not the vibes — say which deserve to exist. Real money is gated behind a pre-committed contract the system itself enforces.

What we built

A fleet on a sealed server: a momentum autopilot rebalancing a paper account monthly; an arena of 19 virtual strategies (momentum variants, risk parity, theme baskets, an ML price-forecast ensemble, an LLM that scores news headlines weekly) with simulated fills and a weekly Telegram leaderboard; a nightly ML forecast job; and an end-of-day report that aggregates everything — including a self-tuning loop that may only adjust parameters once enough evidence accumulates, double-clamped, with fixed-parameter control arms.

Graduation to real money has a written contract: six months of live paper track record, risk and drawdown limits, a kill rule — and the AI is instructed to enforce it against its own operator.

Since then the arena has grown a selection layer that runs itself. Twenty-seven arms now trade paper money side by side, three of which are placebos that pick three random tickers a month, so a strategy that cannot beat coin flips is visible as such. Pre-committed rules promote, retire and cap experiments after every tick, and a fleet-wide death clause writes a tombstone file that halts all trading if every mature strategy has lost to SPY over its own trailing 126 sessions. A parameter-space miner grinds through lookback and moving-average combinations on idle CPU. A research scout reads curated quant feeds and YouTube transcripts each weekday and files testable hypotheses for the experiment loop to pick up.

On 1 August the fleet started writing its own strategies. At 02:30 UTC a headless Codex agent wakes inside a disposable git sandbox holding a copy of the code and a copy of the database, and may edit exactly one file: data/evolved.py. Its loop is invent a pure bars-to-weights strategy, run the test suite, run a walk-forward gate (20 windows of 63 trading days; keep only if it beats SPY on average and wins at least half the windows), then keep or discard the change in git. The orchestrator re-runs the gate independently and copies only that one file into the live arena, where evolved arms are governed by the same retirement, cap and tombstone rules as everything else. Generated code runs behind a wrapper that catches every exception, validates the weights, drops unknown symbols and falls back to the previous allocation. At most five evolved arms may be live at once. It is still paper money only; GRADUATION.md remains the sole route to real capital.

A second lane opened the next night, running at a much faster clock. Cryptolake is a stdlib-only SQLite lake of Alpaca one-minute bars for BTC, ETH and SOL: 2.4 million rows reaching back to August 2024, topped up hourly. Every six hours a NautilusTrader miner walk-forwards a fixed 66-candidate space (Donchian breakouts, SMA crosses and mean reversion, each at 15 minutes and 1 hour) over 21-day windows on a 30-day stride, charging 25 basis points of taker fee on every fill. A window counts as a win only if the candidate beats buy-and-hold and finishes positive, and a candidate is recorded only if it wins at least 55% of at least eight windows, capped at two accepted per day. Warm-up bars are fed in from before each window, so a 200-period average is not judged on the days it spends blind. Nothing that survives this trades: the output is a candidate list for review, and GRADUATION.md is still the only door to real money.

Learnings

  • The bugs are the curriculum. A symbol-format mismatch made one bot liquidate another bot's position; a lookahead bug flattered a forecast; a dropped cash sleeve silently bled a backtest 2% a day. Every one was invisible until honest attribution surfaced it.
  • Fine-tuned models only paid via ensembling with the base model — the standalone fine-tune underperformed both. Measure the combination, not the component.
  • Pre-committed rules (rebalance dates, kill thresholds, graduation gates) are what make an autonomous money system safe to leave alone. Discretion is where both humans and agents go wrong.
  • A foundation model can be confidently wrong in a way that reads as conviction. The Kronos direction feed had five of ten tickers pinned at prob_up 0.00 or 1.00, with five-day expected moves running from −33% to +88%. The model was not making a market call: KronosPredictor z-normalizes its whole lookback window, so on a trending series it regresses toward the window mean, and anything sitting near the extreme of its 400-day range gets an extreme mean-reversion "forecast". The correlation between prob_up and the last close's z-score was sign-perfect across all ten tickers, which means the one ticker that looked sane was the same artifact pointing the other way. Shortening the window to 120 bars moved nine of ten into a plausible 0.37 to 0.86 range. GOOGL still reads 0.01, so this is a mitigation, not a cure.
  • Two of the three forecast bugs were about what the model was fed, not how it was asked. An all-zeros amount column silently suppressed the predictor's own volume-times-price fallback, and yfinance's all-NaN placeholder rows for Oslo listings on weekends crashed the SQLite ingest. Input fidelity first, prompts and parameters second.
  • The containment worked before the feature did. The first evolution run failed because the agent's Linux sandbox needed bubblewrap. The agent reported itself blocked, the gate rejected the empty result, and nothing was promoted. A self-editing system whose default failure mode is "no change" is the only kind worth leaving on a timer.
  • A resume optimisation is a backtest bug waiting to happen. The crypto backfill clamped its start date to the newest bar already stored, which is correct for a daily top-up and silently wrong for a historical backfill: re-running it on a synced lake fetched four bars instead of two years and reported success. Jobs that mean "catch up" and jobs that mean "fetch this range" should not share a code path.

Log

  • 2026-08-02 — Crypto intraday lane live on the same server: a 2.4M-row one-minute lake (BTC and ETH from 2024-08-01, SOL from 2024-08-26) feeding a six-hourly NautilusTrader 1.230 walk-forward miner across 66 candidates. The first smoke run is the useful result: donchian_btc_15m_40 lost 4.8% over a 21-day window across 35 trades, with a 6.4% maximum drawdown. Fees eat naive breakouts, which is exactly why the gate measures candidates against buy-and-hold rather than against zero. No candidate has passed the gate yet.
  • 2026-08-01 — The fleet now edits its own code. Nightly self-editing runtime live: sandboxed Codex agent, one editable file, walk-forward gate, independent re-gate before promotion. The first supervised cycle promoted evo_tactical_dual, a 126-day momentum rotation between QQQ, gold and bonds that the agent wrote unprompted: 12 of 20 backtest windows beat SPY, by 2.7 points on average. It joins the leaderboard at the next tick and is subject to the same retirement rules as every human-written arm.
  • 2026-08-01 — Kronos direction feed root-caused and fixed. Controlled experiment on SPY: lookback 400 gave prob_up 0.00 and −9.0%, 250 gave 0.00 and −4.5%, 120 gave 0.27 and −0.9%. Shipped lookback 120 plus the two input-fidelity fixes, and the reasoning is written into config.yaml next to the number so nobody quietly raises it again.
  • 2026-08-01 — Darwinian selection layer live: automatic promotion and retirement of experiments, a cap of ten concurrent approved specs, and a fleet-wide death clause. Added a parameter-space miner, three placebo control arms, and a weekday research scout feeding hypotheses into the experiment loop.
  • 2026-07-29 — Closed the self-improvement loop: reflections become specs, specs become backtests, backtests become approval decisions.
  • 2026-07-07 — 19th strategy live (LLM news sentiment); learning-loop scoreboard, weekly research routine, and self-tuning EOD report shipped.
  • 2026-07-01 — Momentum autopilot live on a paper account; arena design locked: one arena, strategies as pure functions, honest attribution.