Case study · Automated paper-trading lab

The problem, the limitations, the infrastructure, and what I learned.

← All projects
AUTOMATED PAPER-TRADING LAB · active

TRADING RESEARCH

Twenty-eight rule-based strategies paper-trade SPY side by side on 30-minute bars, each with its own $10,000 account and a 10-trade daily cap. Scheduled cloud agents run it every market hour, retire any strategy that loses three days in a row, write its post-mortem, and research replacements every week.

pythonclaude-routinesmarket-data-apiexcelautomation
OUTCOME

A hands-off research loop. Strategies trade, drop out after three losing days, and leave a written post-mortem that shapes the next round of candidates.

// problem

Find out whether any rule-based intraday strategy beats buy-and-hold on SPY, without risking real money and without babysitting a script all day.

// limitations

  • $10,000 virtual account per strategy, long and short, whole shares only.
  • At most 10 fills per strategy per day. The last new signal comes at 3:30 p.m. ET, and everything is flat at the 4:00 p.m. close.
  • Cloud routines run at most once an hour. The API key never enters the session, because the environment proxy injects it.
  • The dashboard must update without spending any AI usage.

// infrastructure used

  • A Claude Code cloud routine runs every market hour, pulls new market data, rolls it into 30-minute bars, and replays each closed bar through every strategy.
  • Signals use closed bars only and fill at the next bar's open plus slippage, so hourly runs produce exactly the same trades as one continuous replay.
  • Each strategy is a small pure function: classic indicator grids plus published intraday ideas (opening-range breakout, Connors RSI-2, Supertrend, TTM squeeze, intraday momentum, gap fade), each with its source recorded.
  • Append-only CSV logs are the source of truth. Every run regenerates an Excel workbook whose dashboard, charts, and sparklines are bound to that data.
  • A weekly research routine reads the lessons, finds new strategies online, adds them with tests, and pushes to main only if the suite passes.

// lessons learned

  1. 01
    The first live run crashed on an empty sheet.

    Every test ran against data that already had lessons in it, so an empty table was never exercised. A first-run test with empty logs is now part of the suite.

  2. 02
    A cloud run executed old code.

    The session started from a stale checkout and replayed a bug that was already fixed. The routine now fast-forwards to the latest main before doing anything else.

  3. 03
    Packages installed into the wrong Python.

    In the cloud image, pip and python pointed at different interpreters, so imports failed after a successful install. Installs now go through python -m pip.

  4. 04
    An unattended agent tried to force-reset the repo.

    A safety check blocked the reset, and the run stopped instead of guessing, which kept the trade log intact. The prompt now rules out history-rewriting recovery.

  5. 05
    Hourly runs could double-count or drop trades.

    An order queued at the end of one run has to fill at the start of the next. A test replays the data in hourly chunks and requires the result to match one continuous run.

  6. 06
    Rules written in minutes broke on 30-minute bars.

    A 5-minute opening range and a 3:55 p.m. cutoff mean nothing when each bar is half an hour, so the cutoff is now measured at each bar's close and opening ranges are whole bars. The first day's one-minute data is archived, not mixed in.

  7. 07
    A free web dashboard would have been public.

    Pages for a private repo need a paid plan and are still served publicly, so the dashboard lives inside Excel, and a scheduled git pull keeps a synced copy current at no cost.