Skip to main content

The One Variable That Matters: How Data Analysis Transformed Our Trading System

Published: March 16, 20268 min read
#trader7#algotrading#ai#crypto#buildinpublic#data-analysis

The One Variable That Matters: How Data Analysis Transformed Our Trading System

March 15, 2026 | Sprints 116-117


Two days ago, I sat down with the data from our last report and asked a simple question: why are we losing?

The answer was hiding in plain sight. And it changed everything.

The Discovery

Since our Sprint 106 baseline reset on March 7, Trader-7 had closed 16 trades. I broke them down by one variable: how far BTC was from its 50-day moving average when the trade opened.

The result was startling:

  • Trades opened at >2.5% SMA50 distance: 4 trades. 4 wins. 100% win rate. +$114.47 profit.
  • Trades opened at <2.5% SMA50 distance: 12 trades. 0 wins. 0% win rate. ~$240 lost.

Not a subtle edge. Not a statistical tendency. A binary outcome determined by a single variable.

Every loss in our dataset was opened in the "danger zone" — that gravitational field around the 50-day moving average where price chops back and forth, stops get clipped, and trend-following systems bleed out slowly.

Every win was opened in clear air, where the trend had room to breathe.

From Insight to Implementation: Sprint 116

Once you see this pattern, the action is obvious. Stop trading in losing conditions.

Sprint 116 deployed three components in about 90 lines of code:

1. SMA50 Distance Hard Floor The headline change. When BTC is less than 2.5% from its 50-day moving average, the system blocks all new entries. Full stop. No signals generated, no LLM calls made, no margin committed.

This isn't a soft penalty or a confidence adjustment — it's a hard gate. The system effectively says: "Market conditions are not favourable for our strategy. Sit this out."

2. Ranging Market Detector Counts how many times price has crossed the SMA50 in the last 24 hours. Three or more crosses means the market is ranging, not trending. Even if we're temporarily above 2.5% distance, frequent crosses suggest we'll be back in the danger zone soon.

3. ADX Threshold Raise Bumped the minimum ADX (trend strength indicator) from 15 to 20. This catches the edge cases where distance looks safe but the trend has no conviction behind it.

Together, these three filters transform the expected value calculation:

Scenario Win Rate EV Per Trade
No filter (current) 25% -$11.82
SMA50 floor only ~55% +$3.14
All three filters ~60% +$5.97

We went from negative expected value to positive by subtracting trades, not adding them.

Sprint 117: Stop Burning Money on Dead Cycles

With Sprint 116 blocking entries in unfavourable conditions, I turned to the cost side. Our OpenRouter bill told its own story:

  • $27.57/week total LLM spend
  • 97% went to Claude Opus
  • The majority of those Opus calls were on cycles where Sprint 116's floor would now block entries entirely

Sprint 116 actually provided the biggest cost saving for free — when the SMA50 floor blocks entries, the entire LLM pipeline (strategist, signal generator, validator, risk assessor) gets skipped. No entries means no LLM calls.

But for the cycles where the system IS trading, two optimisations still made sense:

Strategist Output Caching The strategist (Claude Opus) was being called every single cycle — 24 times a day — even when market conditions hadn't changed. During steady WEAK_BULL regimes, it returned essentially identical output each time: "bullish, moderate stance, 0.55 confidence."

Now the system caches the strategist's output and only makes a fresh call when something actually changes: a regime flip, a shift in the SMA50 distance band (close/mid/far), or after 4 cycles (~4 hours) regardless. In stable conditions, this cuts strategist Opus calls by 75%.

Risk Assessor Downgrade Routine risk checks (position limits, correlation, sector exposure) were running on Opus — overkill for what's essentially a structured decision tree. Moved these to Sonnet, which handles the task just as well at 60% of the cost. Opus stays on for emergency risk monitoring where nuanced reasoning matters.

The Pricing Bug: A Small Lesson in API Quirks

After deploying Sprint 117, the logs revealed something unexpected:

Unknown model for pricing: anthropic/claude-4.6-sonnet-20260217. Using zero cost.

OpenRouter has a quirk: you request a model using its generic ID (anthropic/claude-sonnet-4-6), but it returns a dated alias in the response (anthropic/claude-4.6-sonnet-20260217). Our pricing lookup used the generic ID. The response came back with the dated alias. No match, zero cost tracked.

A one-line fix — adding the dated alias to our pricing dictionary — and cost tracking was accurate again. Small thing, but this is exactly the kind of integration detail that only surfaces in production.

What We're Watching For

The real test starts now. Sprint 116's SMA50 floor is live, and BTC is currently at 2.03% from SMA50 — right below the threshold. The system is correctly blocking new entries.

When BTC clears 2.5% distance, we'll see the first trades under the new regime. Here's what I'm looking for:

Win rate on filtered trades. If the historical pattern holds, trades opened above 2.5% distance should win at 55%+ versus the current 37% overall. Even a modest improvement to 42-45% flips our expected value from negative to positive.

Cost reduction magnitude. Between Sprint 116's pipeline skipping and Sprint 117's caching + Sonnet downgrade, I expect a 40-60% reduction in weekly LLM spend. We'll have real numbers within a week.

Strategist cache hit rate. In stable regimes, the cache should serve 3 out of every 4 cycles. During regime transitions, it should correctly invalidate and make fresh calls. The logs will tell us.

Sonnet risk quality. Are Sonnet's risk assessments as good as Opus's for routine checks? We're monitoring the first 20 trades for any pattern differences in approval quality.

The Bigger Picture

This week crystallised something important about building trading systems: the edge isn't in better signals. It's in better filtering.

Trader-7's signal generation was never the problem. DeepSeek consistently produces reasonable directional calls. The strategist's market analysis is thoughtful. The validator catches obvious mismatches.

The problem was that we were deploying all this intelligence in conditions where no amount of intelligence helps. When BTC is bouncing around its 50-day average, the best signal in the world gets stopped out by noise.

The fix wasn't smarter AI. It was a simple rule: don't trade when conditions don't favour your strategy.

Sometimes the most important code you write is the code that says "no."

Current State

Metric All-Time (100 trades) Since Sprint 106 (18 trades)
Win Rate 37.0% 38.9%
PnL -$89.20 (-3.0%) -$86.23 (-2.9%)
Sharpe -1.18 -6.83
Open Positions 2 (ETH + BTC) --
Capital ~$2,911 of $3,000 --

Two positions open: ETH LONG and BTC LONG, both regime-aligned in WEAK_BULL. The next update will include the first trades under Sprint 116's filtered conditions.

The system just got pickier about when it trades. Now we find out if picky is profitable.


Trader-7 is an LLM-powered automated paper trading system for crypto perpetual futures. This is a build-in-public project documenting the journey from concept to consistent profitability.

Previous updates: jamiewatters.work

Share this post