Day 28: The Filter Earned Its Keep
The Architecture of Restraint is Hardest to See When it's Working.
I am very close to the end of the first 30 days. I started this as an experiment, 30 Days of TradeBot, but the learning continues. The experiment will continue. And I will keep documenting the project in this space.
Sometimes documenting is a struggle. TradeBot has not executed a single trade for quite some time. Often, on a busy trading day, I will study the log and find potential bugs in the code. But on quiet days, like today the no trade activity becomes the story.
The chip rally on Friday was the kind of move that punishes systems built to fade strength. NVDA, AMD, INTC, and the rest of the chip cluster ran hard. Volume confirmed it. RSI climbed into overbought territory across half the watchlist. Anyone who built a strategy around shorting overbought tape would have spent the day watching their stops fire one after another.
The bot generated short signals on six of those names.
It executed zero of them.
This is the part of the system I rebuild in my head whenever I get nervous about whether the bot is doing anything. The VWAP filter, which was added quietly weeks ago, sits between signal generation and order execution and asks one question: is the price on the wrong side of the volume-weighted average for the direction I’m about to take? If the answer is yes, the trade is suppressed. Not delayed. Suppressed entirely.
On Friday, the filter blocked six SELL signals across NVDA, AMD, QQQ (twice), and SPY (twice). Each one would have shorted into a tape that kept rising for the rest of the session.
Final equity: unchanged. The bot ended Day 28 at exactly the same dollar it started: $101,105.72.
Zero trades. Zero P&L. And I’m calling it a good day.
This is the part of building a trading system that took me weeks to internalize. A flat day where the system correctly stayed out of a contested market is not nothing. It’s the system doing exactly what it was built to do.
Day 21 was the first time I saw this clearly. Short squeeze morning, signals firing on overbought conditions, VWAP filter suppressing every entry. Same pattern. Day 22: peace rally, system generating SELL signals across QQQ, SPY, TSLA, ORCL, filter blocking ten potential trades.
Day 28 was the third time. The filter is no longer a feature I’m watching to see if it works. It’s a feature I’m watching because not seeing it work is the data point that would worry me.
There’s a story buried in the day that’s worth telling because it’s the one place where the system showed its current ceiling.
Late morning, the bot scored an INTC headline: “Intel Reports Q1 Beat, Yet These Analysts Remain Bearish.”
The local language model running in shadow mode read that as +0.65. A strongly bullish signal. The Claude API, also scoring it for comparison, read it as -0.20, mildly bearish. That’s a delta of 0.85, which is enormous in a system that classifies anything above 0.35 as a meaningful disagreement. The local model anchored on “Q1 Beat”. A bullish surface phrase. It missed the rest of the sentence. The qualifier “Yet these analysts remain bearish” was right there, and the local model walked past it.
This is the part of the experiment that stays interesting. The local model is trained on roughly 110,000 historical headlines, with another 320,000 in the v2 training set. On Day 27 it scored 100% agreement with the API on the high-conviction headlines that actually drive trading decisions. Twelve out of twelve. The cutover analyzer literally printed READY FOR CUTOVER.
I held. Day 28 is why.
The headline counts don’t tell the cutover story by themselves. The shape of the failure does. Day 27 was clean across twelve clear-signal headlines. Day 28 missed one, but it missed it on a high-conviction call. The kind of headline that would actually fire a trade if the local model were running live.
That’s the discipline this experiment has been training into me from the beginning. Cutover requires sustained performance, not single-session qualification. One good day doesn’t earn the switch flip. One bad day on a clear signal doesn’t kill the local model’s trajectory either. But it does mean the data isn’t there yet. And the data is the only thing that decides.
I’d rather hold for as many days as the data takes, than flip the switch and discover the failure modes the hard way.
Two days left in the experiment. The system has now run for 28 trading days through a sustained FEAR regime, VIX 28 to 38, without ever exceeding 1% drawdown. Six VWAP filter blocks on Day 28 alone is the strongest single-session evidence so far that the filter is doing structural work, not situational work. The architecture is holding.
Maximum drawdown under 1% across 28 days is the most encouraging number in the experiment, and it’s the one that gets the least attention because it’s not a P&L line. It’s an absence. A negative space. The size of the loss the system did not take.
That’s the thing I’m trying to learn how to write about. The flat days. The blocked trades. The signals suppressed before they became losses. The whole architecture of restraint that gets harder to see the better it works.
Day 28 is what that looks like in a single session.



Exciting as 30 day timeline approaches...!