05 about
What this is
Monkey vs Machine is a fully simulated stock-trading experiment. Every US trading day, a single AI trader and a pack of 100 random "monkey" traders each make their next move on real historical S&P 500 prices. The dashboard tracks all of them.
How it works
- Once per US trading day, a "tick" runs on a dedicated Linux box. The tick fetches the new daily bar, retrains the AI on every available day of price history, and rebalances the AI's portfolio into the top-10 stocks it predicts will rise over the next 5 days.
- Each of the 100 monkeys advances one day too. Each monkey holds at most one stock at a time. On any given day a monkey has a 5% chance of trading; when it does, half the time it sells what it holds and half the time it buys a uniformly-random ticker from the universe.
- Both the AI and the monkeys start with the same $10,000 in cash and pay the same 5-basis-point cost on every trade. The race is over real bars; there is no look-ahead.
What the AI is
- A scikit-learn HistGradientBoosting classifier trained on engineered price features: 1/5/20-day returns, 14-day RSI, MACD signal, 20/60-day return volatility, volume z-score, and abnormal return.
- Walk-forward retrained every tick with a 5-day forward-return target. The training window's edge is shifted back by the forecast horizon so the label can never peek at the prediction date.
- Swappable by design. The codebase keeps the AI behind a
MODELSregistry. Adding a LightGBM or stacking ensemble later is one entry in a dict. The schema is model-keyed from day one.
Why monkeys
Markets are noisy enough that a single "AI beats the market" story is almost never falsifiable on a single run. A pack of 100 random traders gives a real null distribution: if the AI lands at the 50th percentile of the monkey pack, it's mostly noise. If it lands above the 95th percentile and keeps doing so, that's signal. The dashboard shows the mean of the monkey pack as a single random-portfolio line so you can judge for yourself.
Caveats
- Survivorship bias. The universe is the current S&P 500 fallback list. Companies that dropped out are missing.
- No real money. The AI's picks are not placed on any broker. A stub interface exists for a future Alpaca-paper integration.
- Live news is decoration, not training. Historical news isn't available retroactively, so the AI is trained on price-derived attention proxies rather than real sentiment.
- Deterministic. A tick re-run on the same date with the
same pinned environment produces byte-identical state. See
DETERMINISM.mdin the repo for the contract.
How a tick actually runs
Every weekday afternoon (Brisbane time) my laptop wakes up and the Windows
Task Scheduler logon trigger fires update.ps1. That script
walks any missed weekdays via scripts/catchup.py, runs the
simulation locally, then POSTs the published rows to /admin/ingest on this dashboard. Cloudflare D1 stores the
public mirror; the SvelteKit pages you're looking at read from D1 with a
60-second edge cache. The 100 unnamed monkeys live in a SQLite file
on the laptop and never get pushed.
Source
Code on GitHub ↗. Compute is Python + scikit-learn; the dashboard is Svelte 5 + Chart.js deployed on Cloudflare Pages with a D1 read-only mirror.