the brain
how it decides what to change
The trading is the easy half. The interesting half is what happens between two versions — how a set of losing fills becomes an argument, and how the argument becomes a line of code that can be proved wrong.
- 01
measure what happened
Pull every fill since the last deploy. Not the equity curve — the individual trades, with the reason each one closed. A version that made money on one lucky runner and lost on nine stops is not a version that made money.
fills({ since: lastDeploy })
- 02
find the shape of the loss
Group the losers. If they share an exit reason, the exit is wrong. If they share an entry hour, the filter is wrong. If they share nothing, there is no lesson here and the right change is no change.
group(losers, by: 'reason' | 'hour' | 'regime')
- 03
state the hypothesis in one line
Written before the code, because a change with no prediction attached cannot be wrong later, and a change that cannot be wrong cannot teach anything.
commit.message
- 04
write the patch
One idea per version. A commit that moves the stop and the trigger and the size cannot be reviewed by its result — whatever the number says, three things could have caused it.
edit('strategy.ts')
- 05
flatten, then ship
Close any open position first. A version should never be credited with a trade the previous version opened, or blamed for one it inherited.
flat() -> deploy(version)
- 06
wait longer than is comfortable
Then go back to 01. The temptation is to judge a version after two trades, and on a fifteen-minute chart two trades can happen inside an afternoon. Two trades is noise wearing a number's clothes.
sleep(untilEnoughFills)
evidence
twelve days is an anecdote
The rest of this site shows a single run — 22 trades, one tape, +12.1% a day. A pair that goes up for twelve days will make almost any long-only bot look clever, so every version was also run over 1,500 independent tapes it has never seen. The column that explains the whole ladder is the last one but two: how much of the time each version is actually in the market.
every guardrail costs return
The trend filter, the stop and the volume gate each take a point or so off the daily rate, and each one does it the same way: by taking the bot out of the market. v0.4 is in the market 47% of the time and it is the worst version here.
the trail is what earns it back
v0.5 keeps every one of those guardrails and still beats the unprotected v0.1, because holding a winner for 64 bars instead of 40 is worth more than the entries it declines. That is the only version where a rule was added and the number went up.
v0.5.1 measured worse
Requiring the mean to be rising sounded like a better filter. It cut time in the market from 58% to 53% and about a point a day off the return. It is in the log struck through, which is the only honest place to put it.
And the number this page exists to admit: on the tape this site shows, buying GROK/SOL and doing nothing at all returned +738.0%, against the desk’s +278.5%. The agent is in cash roughly a third of the time, so in an uninterrupted run it cannot beat the thing it is trading — it takes a smaller number in exchange for a 12.5% worst drawdown instead of whatever the pair felt like handing out. Whether that trade is worth making is the open question, and it is the first thing on the list below.
constraints
the parts it is not allowed to touch
An agent with commit access to its own strategy will eventually write the commit that removes its own guardrails. These live outside the file it can edit.
long only
It can be in the pair or in cash. There is no short, so a falling market is a market it sits out.
no leverage
Position size is a fraction of the book. The worst case is a bad month, not a liquidation.
one pair
GROK/SOL. Adding pairs would let a losing idea hide behind a winning one.
flat before deploy
Every version starts with no inheritance and ends owing nothing to the next.
one change per version
So the result can be attributed to something.
costs are real
0.30% a side plus slippage comes out before anything is called profit.
open questions
what v0.7 is probably about
Stated in advance so it can be checked against what actually ships.
Even at v0.6 it is flat about a third of the time, and in a run that is the entire gap between what it made and what simply holding the pair made. Closing that gap means either entering earlier or never fully exiting, and both undo the reason the drawdown is small.
Every entry is the same 95% of the book whether the setup is the best of the week or the fourth-best of the hour. Nothing in the file ranks them, so nothing can size to the ranking.
8% was chosen because it beat 10%, which beat 13%. That is a direction, not a measurement — three points on a curve nobody has actually swept.