A warning before we start. This is a deep dive into the live development of a trading system, with kill lists, exit tables and confession commits intact. I am fully aware that the audience for this level of detail is me, plus the occasional stranger who genuinely loves the data. If that is you, welcome, pull up a chair. Everyone else is free to skim to the scoreboard and judge me on the totals.

I have not said much about my stock-trading system lately. Regular readers last saw it in June, at the end of a piece about poisoned data, reduced to a single share. A monument, I called it. What I did not fully explain at the time, partly because the story was still happening, was what came next.
What came next is that I killed it. Deliberately, on evidence, one subsystem at a time. Then I replaced it with the most boring trading strategy I could design, and spent the summer finding out whether boring actually works.
The usual disclaimer goes up front, where it belongs. Everything in this article is a Trading 212 demo account. The prices are real, the money is imaginary, and the only thing genuinely at stake has been my confidence in my own numbers, which previous articles have established is fragile enough already.
The system is called Gekko, after the man who told us greed is good. The joke of this piece is that three months of production data have turned it into Warren Buffett. Not in returns. Very much not in returns, as we will get to. In temperament. The question I have been circling all summer is whether the new system is boring boring or Warren Buffett boring, because those are not the same substance. One is boring because nothing is happening. The other is boring because everything unnecessary has been removed.
Back in May I wrote about Robinhood handing AI trading tools to the public, and I promised the interesting part was what you do after momentum-chasing fails. This is that. Buckle in, though at the new system’s preferred pace, which is glacial.
The audit
On the first of May I sat down with ninety days of the system’s own production data and did forensics on it. Not vibes. Not a bad week and a temper. A structured post-mortem of a live system, using the records it had been dutifully keeping about itself the whole time.
The headline findings, straight from the audit commit: a 36.4 per cent win rate across 341 closed trades. A take-profit to stop-loss ratio of one to fourteen. Eighty-three per cent of the system’s own post-trade reflections said it would not take the trade again, which is a remarkable thing for a system to keep writing down while continuing to take the trades. The benchmark audit put it more plainly: the demo account was bleeding about £14 a day while the index was flat to up. The alpha column was negative or near zero every single day.
There is no reading of those numbers that says tune it. Every subsystem got sorted into a tier with a verdict attached: keep, retune, merge, delete. A lot of them got delete.
Every kill had a number attached
This is the part I am quietly proud of, because the temptation with a losing system is to rage-quit it in an afternoon. Instead, each subsystem was executed individually, with its own evidence read out first.
The LLM defensive-sell trigger had lost £44 over ninety days with a 93 per cent regret rate in its own reflections. Killed on the first of May. The rotation logic had lost £23 with zero out of twelve trades it would take again. Killed the same day. UK entries, which readers of the last piece already saw condemned, went on the thirteenth: 86 trades, £82 lost, a 28 per cent win rate, and an audit that ruled the problem was selection rather than fills, which stung, because bad fills would at least have been someone else’s fault. The two opening scan windows went next, having produced exactly three take-profits across 96 closed trades. On the nineteenth of May the entire chase pipeline was gated off before any model was ever called, saving five to fifteen dollars a day in tokens for signals that no longer had anywhere to go.
The most instructive corpse was the five-model panel. The original design had five LLMs debating every trade, on the theory that no single decision-maker should be trusted. A fine principle. The execution, it turned out, was theatre. The Bull role voted BUY 61 times out of 61. The Momentum role voted HOLD 62 times out of 62. Two other roles ran on the same underlying model, so the five-way consensus was really three voters pretending to be five, and one of them was a rubber stamp.
Then I fixed it, and the fix made it worse. After a prompt rewrite, the Analyst role voted BUY on 48 out of 48 candidates against a target of roughly half. High-conviction agreement, the signal the whole design existed to produce, collapsed from a 50 per cent hit rate to 12.5.
Meanwhile a deterministic challenger, a plain rules-based checker with no model in it at all, was auditioned against the panel in replay. On the days they disagreed, 24 stocks the panel wanted to buy and the boring rules rejected went on to average minus 2.25 per cent by the end of the day. In a five-day live shadow run, the deterministic side finished £34 up across 20 closed trades while the panel finished £151 down across 11.
I will let my own hypothesis log deliver the verdict on my analytical process during this period, from an entry dated 24 April: “I produced four successive diagnoses of the panel today, each contradicting the last.” Diagnosis two turned out to be a SQL bug. Diagnosis three was me over-reading seven data points. Diagnosis four graded the whole thing an A. When your debugging log reads like that, the panel is not the only thing that needs replacing.
Final ledger for the chasing era, verified against the database: 503 completed trades between February and the end of May, a 38 per cent win rate, £212 down. Not one dramatic crash. Hundreds of small, fast, adverse moves spread across 55 of roughly 63 trading days. Death by daily churn.
Boring on purpose
On the eighteenth of May, with the portfolio down to its one commemorative share, the replacement shipped. Thirty-six files, 2,708 lines, paper-only to start. I described its outline in the last article, so here I want to talk about its personality, because the personality is the point.
The entry signal is a 20-day z-score. A stock qualifies when it closes more than 1.8 standard deviations below its own 20-day average, which is the bottom few per cent of its normal behaviour. A typical liquid quality stock does this a few times a quarter. There is no AI in the entry path at all, which given the founding principle of this system is a punchline I did not see coming. “No single decision-maker is trusted” used to mean five language models arguing. It now means zero language models and a replay harness that audits every rule change instead. Same principle. Considerably cheaper.
One simulation does all the thinking. A bootstrap Monte Carlo resamples the last year of the stock’s actual daily returns, five thousand paths over a 20-day horizon, no tidy textbook assumptions, because real quality stocks have fat tails and the resampling keeps them. That single distribution then does three jobs: it sizes the position at half-Kelly capped at five per cent, because full Kelly on tail-heavy data is a confident idiot; it sets the stop at the fifth percentile of the path minimums, the worst plausible drawdown along the way rather than just at the end; and it sets the target at the 75th percentile of the path maximums.
The quality filter is index membership. If a company is in the S&P 500 or the FTSE 350 and my broker carries it, it is in the universe. No hand-curated list of favourites to maintain, nothing to argue with, fully reproducible.
The very first scan told me the design was working. Universe of 104 names, four triggered, zero opened. A sharp drop that fires the dip signal also shows up in the bootstrap as elevated downside risk, so the maths declined to catch the knife. The strategy’s first recorded act was to refuse its own signal four times in a row. I have built a lot of systems over the years. Very few of them opened with a display of restraint.
Warren Buffett has that line about the market being a device for transferring money from the impatient to the patient. The old Gekko spent two months on the wrong end of that transfer. The new one was designed from the first commit to sit on the other side of the table.
The temperament transplant
Getting it from paper to the live demo account took 36 hours, which sounds heroic and was actually just the payoff from a refactor and a shadow-broker harness that already existed. The interesting work was not the cutover. It was discovering that the babysitting layer, all the monitors that watch open positions, encoded the old system’s worldview, and that worldview was the opposite of the new one.
The chase era’s protection logic existed to kill trades that did not move within hours. No-progress floors, time-decay tightening, stalled-position detectors, all of it built on the belief that a good trade proves itself immediately. The new strategy’s entire thesis is that positions look bad for days before reverting. Run the old monitors over the new book and they would execute every position at exactly the moment the thesis said hold your nerve.
So the monitors got inverted. The hard stop widened from six per cent to fifteen. The no-progress floor was removed entirely, because it would chop day-one dips before the reversion had any chance to play out. No trailing stop engages until a position has been up five per cent. Best illustration of the culture clash, from the 22nd of May: a three-day-old position sitting at plus 4.4 per cent, comfortably inside its simulated envelope, got flagged SELL by a leftover piece of chase logic on the strength of a bearish momentum indicator. The fix made HOLD the default answer. The thesis is patience. The code now agrees.
A strategy is not an entry signal. It is a worldview, and every layer of the system either shares it or fights it.
A summer of nothing erroring
Here is the theme of the summer’s incidents, and if you read the last article it will sound familiar: in every serious failure, nothing errored. The tell, every single time, was quiet.
The memory leak first. The library this whole operation uses to fetch free price data spawns one thread per ticker by default and never reclaims the stacks. After nine days of uptime the process had swollen to 254 gigabytes of virtual memory on a small home computer, roughly thirty-one thousand leaked eight-megabyte stacks, and every part of the system that needed to start a thread was dying quietly, 1,145 failures since four in the morning, position protection offline for five hours. The service manager was configured to restart on crash. It never restarted, because the process never crashed. It stayed alive while functionally dead, and I had built no protection against alive-but-degraded. The truly annoying detail: a June patch had already fixed this leak at one call site. There were fourteen. Leaking was the default, so every other call site leaked by omission. The final fix wraps the function once for the whole process and adds a lint test that fails the build if the bad default ever comes back.
Then the data corruption, which produced the most honest commit message I have ever had to stand behind. On the 24th of July, the free feed served a full US session with volume populated and every price field null, while the UK side came through fine. The freshness guard only asked when the refresh had last run, a question that cannot detect a refresh that runs on schedule and brings back nothing. Apple moved three and a half per cent that day, and every US z-score was quietly being computed over a window with a large up-day missing from the middle of it. For two days the diagnosis, delivered to me with some confidence, was an upstream Yahoo defect: permanent, nothing to be done. Then came the confession commit, which records what actually happened: the data had been there all along, and our own client library was three minor versions stale and could not parse the row. Second time a stale version of that library has silently corrupted data this year. Both times, the tell was that nothing errored.
The rebuilt freshness guard is now properly paranoid. It counts trading sessions rather than hours, because a Monday scan holding Friday’s bar is current and the same gap on a Wednesday is not. It checks per exchange, so a stale US feed no longer grounds UK trading. And it measures coverage rather than the newest bar, because at one point the feed returned Friday’s data for exactly one of five hundred US names, and taking the maximum would have declared the whole book current on the strength of that one ticker. Quiet is exactly what a broken feed looks like from outside.
My favourite pair, though, is the two currency bugs that cancelled each other out. Bug one: a £250 budget divided by a dollar price bought 250 dollars’ worth, about £186, so every US position was 26 per cent undersized. Bug two: trade profits were stored in whatever currency the trade happened in and then summed as if it were all pounds. Each bug alone would have shown up in the headline number. Together they roughly cancelled on realised profit, so the total looked plausible and neither surfaced. I only found them by investigating why the book had drifted to seventy per cent UK names. They had to be fixed together, because fixing either one alone would have broken the accidental agreement and made the numbers worse.
And one last entry for the silence file. A chase-era circuit breaker, the pause-after-consecutive-losses kind, armed itself on the eleventh of June with a hardcoded freeze of 365 days, then said nothing. For two weeks every entry was rejected with a note that the pause would lift in roughly 8,418 hours. The book it was protecting was fine, about £60 up. It was the second offence: in May the same breaker had tripped on five small, controlled exits averaging minus 2.1 per cent, which is to say it punished the system for doing exactly what the loss-cutting rules were designed to make it do. It now pauses for 24 hours at most and puts a large banner on the morning report, so a multi-day freeze can never again be a thing I discover by archaeology.
Replay, not vibes
The old system was tuned by intuition and prompt-poking, and you have seen how that went. The new one changes its behaviour a different way. Build a harness. Replay history. Hold everything fixed except one variable. Ship only what strictly wins, and ship it in shadow first.
The best example is the trial where the suspect turned out to be innocent. In June the book went quiet, and the obvious culprit was the Monte Carlo gate, which was rejecting around eighty per cent of triggered signals as not worth the risk. It genuinely looked like it punished exactly the names the entry signal liked. The old me would have loosened it. Instead, a replay harness re-ran 43,508 historical triggers across 861 names over three years, testing the production gate against three looser variants. The production gate won on every quality axis. Highest expectancy per trade, best profit factor, and a maximum losing streak of 20 against 62 to 102 for the looser versions. The decisive number: trades the gate admits average plus 0.86 per cent, trades it rejects average plus 0.29, a separation of about five standard deviations. The gate was acquitted. The actual culprit was the 365-day breaker from the previous section, sitting silently in the corner the entire time.
The same harness then found a lever I had not even thought to look for. The strategy generates far more signals than the pot can hold, and it had been filling slots first come, first served, which is actively bad, because the earliest dips in a cluster are often the start of the selloff rather than the bottom of it. Ranking candidates by their Kelly score before filling slots roughly doubled the replayed profit. The engineering punchline is that the score was already computed for every candidate. The entire fix was replacing iteration order with a sort.
Just as important is what shipped switched off. Let-winners-run tested neutral to worse, and the smoke test that flattered it turned out to be survivorship bias. A tighter trailing stop gave back three hundred percentage points in replay. Only one exit refinement survived, a surgical cut for confirmed bleeders, and even that went live in shadow mode, logging what it would have done, with its acceptance test written before the data arrives.
Every deliberate change now gets a written prediction with an evaluation date, committed alongside the change itself. In the spirit of that log, an honest confession about the log: it holds 61 predictions and only two filed verdicts, with several past their review dates unmarked. By its own stated standard, the log is still on probation. So is its author.
The scoreboard, honestly
All figures as of the twelfth of August, demo account throughout, no real money anywhere in this series.
Since the nineteenth of May the quality book has closed 156 trades for a total of plus £198.85. The win rate is 56.41 per cent. The average win is plus 5.28 per cent and the average loss is minus 5.28 per cent, which is a strangely perfect symmetry with an important meaning: the entire edge, such as it is, lives in the win rate. This system does not cut losers short and let winners run. That was the strategy it replaced. This one just tries to be right slightly more often than it is wrong, at identical stakes.
The number that best captures the temperament change is this one: those 156 entries were selected from 11,849 rejections. Buffett is fond of saying that really successful people say no to almost everything. My system now says no 76 times for every yes, which by that measure makes it the most successful thing I have ever built.
Where the money actually came from:
| Exit reason | Trades | P&L | Avg % |
|---|---|---|---|
| Take-profit (MC target) | 21 | +£385.51 | +10.95 |
| Rotation | 27 | +£59.37 | +1.00 |
| Stop-loss, incl. trailed | 75 | +£42.32 | +0.15 |
| Stop breach | 4 | +£32.58 | +3.67 |
| Stale | 1 | +£0.85 | +1.16 |
| Cutover bookkeeping | 6 | -£60.68 | -5.85 |
| Hard stop | 22 | -£261.10 | -6.27 |
Twenty-one take-profits against twenty-two hard stops. That is the shape of the strategy in one row pairing: it is a knife-catcher by design, and roughly one dip in seven turns out to be the start of a genuine collapse. The wide Monte Carlo targets that a June report graded harshly for almost never being hit are precisely what paid for August.
About August. The monthly sequence reads plus £6.59, minus £5.06, plus £5.07, plus £192.24. Ninety-seven per cent of the realised profit arrived in the first twelve trading days of August. Two readings of that coexist and I am not going to pick one for you. The tuning finally landed. And twelve good days is twelve good days.
Now the index comparison, and this is where I have to show you three scoreboards, because they disagree and the disagreement is the honest part. The dashboard’s daily alpha chart says the trade ledger is fractionally ahead of the S&P 500 since May, by 0.27 percentage points, having beaten it on 25 days and trailed on 32. The account statement says the demo equity grew 2.57 per cent while the S&P grew 3.97 in dollar terms, so trailing by about 1.4 points. And the fair comparison for a UK investor, since the account is in pounds and the index is not, prices the S&P at roughly 3.4 to 3.5 per cent in sterling terms over the window, putting the honest gap at about 0.9 points, or around half a point after that investor’s own conversion and fund costs. Currency explains a third of the shortfall. It narrows the verdict. It does not flip it.
Why do the scoreboards disagree? Partly cash drag the ledger cannot see. Partly the difference between ledger marks and broker marks. And partly because on the 21st of July the currency-accounting fix backfilled history and the ledger jumped £119 in a day through revaluation, not trading. Even the measurement layer had bugs: two weekly benchmark reports printed literal nan where the alpha should be, three reports recorded three different index figures for the same week during the data-corruption saga, and for a while the dashboard displayed all three market indices at exactly 0.00 per cent whenever it could not compute a change, which reads as a calm market and is actually a fabrication nobody can spot by looking. The scoreboard needed debugging as much as the trader did. In a system whose stated design intent is to be a measurement instrument that happens to trade, that is the failure that bothered me most.
The one contrast I will allow myself, once: the old system’s final benchmark audit read minus 4.6 per cent in ten days while the index ran plus 10.5 in thirty. The new one is level with the index to within noise on 156 trades. That is not victory. The system’s own written bar is to beat the index over rolling windows by enough to distinguish alpha from noise, and by that bar it has not passed. It has done something the old one never managed, though. It has earned the right to keep collecting data.
The Oracle of the Living Room
I should say, for readers keeping score across articles, that this entire operation still shares a shelf with a paper-money horse tipster, and I have not read a single line of the code in either of them. Gekko alone runs to thirty-one thousand lines of Python across sixty-odd services, written by AI, audited by AI, corrected by commits whose confessions I quoted above. The transcripts and the logs are the ground truth now, not the code, which is a sentence I keep writing in different articles because it keeps being the lesson.
Three bets are on the record with verdicts pending. The surgical bleeder-cut is live in shadow, logging what it would have done. The Kelly-ranked execution has a live confirmation window open against its replayed promise. And on the twentieth of August, eight days after this article’s data cut-off, the currency-fix hypothesis grades its own homework: the replay says the US book’s edge is more than three times the UK’s, the small live sample says the opposite, and the falsification criteria were written down before the answer existed.
The plan was always to go live with a modest real pot once the demo could beat the index by more than noise. It cannot yet, so it will not. Either it earns that or it gets killed again, by the same method as last time, with every kill carrying a number.
Somewhere in Omaha there is a man who has spent seventy years demonstrating that doing almost nothing, extremely well, on the basis of patient arithmetic, beats doing everything at speed. It took me 503 losing trades, five arguing language models, and a 254-gigabyte memory leak to arrive at a small domestic version of the same conclusion, running on a mini PC next to the television. Boring was never the compromise. Boring is what a strategy looks like after everything that could not justify itself has been removed, and the removals are the work.
The figures here are drawn from the system’s own production database, git history, and hypothesis log, verified on 12 August 2026. The account is a Trading 212 demo throughout, and no real money has been staked or lost.
The views expressed in this article are my own and do not represent the views of my employer.