From Missed Profits to Data-Driven Precision: How I'm Building my Trading Bot's Entry Timing System
From Missed Profits to Data-Driven Precision: How We're Building Trader-7's Entry Timing System
Date: December 13, 2025 Author: Jamie Watters Series: Building an AI Trading Bot in Public
The Problem That Started It All
On December 10th, I watched my trading bot do something frustrating. ETH hit $3,449—just $19 shy of the $3,468 take profit target. Then it retreated. By the time the bot woke up for its hourly check, the opportunity was gone. The position later stopped out for a loss.
Same story with SOL. Price touched $142.63, missing TP by $4. Another loss.
The bot was running on 1-hour cycles. In paper trading mode, that meant TP/SL orders were only checked when the bot woke up. In choppy markets, price can touch your target multiple times during an hour—but if you're asleep, you'll never know.
This is the kind of problem that keeps you up at night. Not because it's complex, but because it's so obviously fixable.
Sprint 29: Quick Monitoring Sub-Cycles
The solution was elegant: instead of sleeping for a full hour between trading cycles, add lightweight "quick monitors" every 15 minutes.
Hour 0:00 - Full cycle (AI analysis + position monitoring + new trades)
0:15 - Quick monitor (price check + TP/SL detection ONLY)
0:30 - Quick monitor
0:45 - Quick monitor
Hour 1:00 - Full cycle
The key insight was separation of concerns:
Quick monitors do:
- Fetch live prices for all symbols
- Check pending orders for TP/SL fills
- Update MFE/MAE tracking for open positions
Quick monitors don't do:
- Call AI/LLM APIs (expensive, slow)
- Generate trade proposals
- Execute new trades
- Run validation pipeline
This is cheap, fast, and focused. Each quick monitor completes in under 10 seconds. No API costs. No complex decision-making. Just: "Has price crossed any of our levels? Yes/no."
The December 12th Test
Sprint 29 went live, and December 12th became our first real test.
The bot ran 15 full cycles and 43 quick monitors—58 total position checks across a 15-hour trading day. And then the moment of truth arrived.
At 3:14 PM, the last full cycle completed. At some point between 3:14 and 3:29, ETH price dropped and triggered our stop loss at $3,166.87.
Without Sprint 29: The bot would have slept until 4:14 PM. The stop would have been hit, but we wouldn't detect it for ~45-50 minutes. In volatile markets, that's an eternity of additional slippage risk.
With Sprint 29: Quick Monitor #1 ran at 3:29 PM and immediately detected the stop. Position closed at 3:29:25—one second after detection.
Sprint 29 saved us 45 minutes of exposure. The stop executed cleanly at $3,158.10 with minimal slippage.
The Scorecard
| Metric | Target | Actual |
|---|---|---|
| Quick Monitor Frequency | 15 min | 15 min |
| Quick Monitor Reliability | 100% | 100% (43/43) |
| TP/SL Detection Speed | <1 min | <1 second |
| Time Saved vs Hourly | 30-45 min | ~45 min |
| System Stability | No crashes | 0 crashes |
Verdict: Sprint 29 is production ready.
But Wait—We Found a Bigger Problem
While analyzing the December 12th data, something else caught my attention.
The ETH position that got stopped out had been open for 16 hours. It peaked at +0.99% (a modest $32 profit on paper), then reversed 2.27% to hit the stop.
The entry wasn't bad. It was just... mediocre. We entered during a shallow pullback in what turned out to be a choppy, range-bound market. ADX was weak (11-22). There was no strong trend to ride.
And this got me thinking: We're solving the wrong problem.
Sprint 29 helps us exit trades faster. But what if we shouldn't have entered in the first place?
The Insight That Led to Sprint 30
Looking at our trade history, a pattern emerged. Our AI strategist is reasonably good at picking direction. When it says "go long ETH," ETH often does go up... eventually.
But the AI answers the wrong question.
What the AI answers: "Should I be long or short this symbol?"
What the AI doesn't answer: "Is NOW a good time to enter?"
These are completely different questions. You can be right about direction but wrong about timing. You can be bullish on ETH and still get stopped out if you enter at the top of a local move.
The December 11th BTC trade was a perfect example:
- BTC LONG entered at $97,393
- Stopped out at $96,900, -$16.94
- Entry was late in the move, price was extended from the moving average
The direction wasn't wrong. The timing was wrong.
Sprint 30: Entry Timing System (Coming Soon)
We've designed a solution: an Entry Timing Validator that scores entry quality on a 1-10 scale before execution.
The factors we'll evaluate:
| Factor | Weight | What It Measures |
|---|---|---|
| Distance from 20 EMA | 25% | Are we chasing or catching a pullback? |
| RSI Position | 20% | Room to move in our direction? |
| Candle Pattern | 15% | Momentum or consolidation? |
| Volume Profile | 15% | Normal trading or exhaustion climax? |
| Bars Since Move Start | 15% | Fresh breakout or late to the party? |
| 15m TF Alignment | 10% | Does the lower timeframe confirm? |
The decision matrix:
| Score | Action |
|---|---|
| 8-10 | Market order immediately |
| 6-7 | Limit order at pullback level |
| 1-5 | Wait, re-evaluate next hour |
This doesn't replace the AI's direction call. It complements it. The AI decides WHAT to trade. Entry timing decides WHEN.
But We're Not Implementing It Yet
Here's where discipline matters.
We have the design. We could implement it today. But we'd be guessing at the thresholds. What should the minimum score be—5? 6? 7? How should we weight the factors? Should EMA distance matter more than RSI?
We don't know yet. And implementing without data is just adding complexity without evidence.
So instead, we're doing something smarter: collecting data.
The Data Collection Plan
For the next 5-10 trades, we're tracking:
- Entry price vs local low (how far from optimal?)
- ADX value at entry time
- Time to first 1% move (up or down)
- Time to TP1 (or stop loss)
- Market regime (trending vs choppy)
We want to answer questions like:
- Do low-ADX entries have worse outcomes?
- Does entering near the 20 EMA correlate with faster TPs?
- Can we predict "slow/stuck" trades before they happen?
What We're Looking For
Good entries (fast TPs):
- Close to moving average (not extended)
- Fresh move (early in trend)
- Aligned across timeframes
Bad entries (quick stops):
- Extended from MA (chasing)
- Late in move (exhausted)
- Divergence between timeframes
Stuck entries (slow/no TPs):
- Mid-range positioning
- Low volatility/conviction
- Weak trend strength
Once we have the data, we'll tune the thresholds with evidence instead of intuition.
The Overnight Bug (A Debugging Story)
Just when we thought Sprint 29 was perfect, December 13th threw us a curveball.
At 6:55 AM, the bot identified an excellent ETH SHORT setup:
- 85% confidence
- RSI 35 (oversold in a downtrend—bearish confirmation)
- 3:1 risk/reward
- Passed all validation checks
The trade opened successfully. Database confirmed. Tax lot created.
Then, 3 seconds later, reconciliation ran. It checked the exchange adapter, found 0 positions, compared that to the database's 1 position, and decided we had an "orphan" trade.
Auto-close triggered. Trade killed. $0 P&L.
The Root Cause
This was a synchronization bug. Orders were being routed through the spot adapter, but reconciliation was checking the perpetual adapter. Different adapters, different position caches, false orphan detection.
We fixed it this morning (Sprint 31). OrderManager now routes perpetual symbols to the perpetual adapter. Reconciliation sees positions correctly.
But the lesson is important: infrastructure bugs can mask strategy performance.
If this bug had been running silently for weeks, how many "missing" trades would we have lost? How skewed would our statistics be?
We're now auditing historical logs to find out.
The Current State
What's working:
- Sprint 29 quick monitoring (catching TPs/SLs 45 min faster)
- AI strategist selectivity (correctly rejecting 75+ weak setups yesterday)
- Risk management (stops protecting capital)
- Sprint 31 fix (orders routing correctly)
What needs improvement:
- Entry timing (the core Sprint 30 objective)
- Win rate (26.8% is below breakeven with fees)
- Choppy market detection (avoid low-ADX entries)
What we're collecting:
- Entry quality metrics for Sprint 30 tuning
- Trade outcome correlations
- Evidence for threshold decisions
The Philosophy
Building a trading system is an exercise in humility. You think you've solved one problem, and two more appear. You fix a bug, and realize it might have been affecting your data for weeks.
But that's the process. Ship, observe, learn, iterate.
Sprint 29 solved the monitoring problem. Sprint 30 will solve the entry problem—once we have the data to do it right. Sprint 31 fixed a bug we didn't know we had.
Each sprint makes the system a little smarter. Not through guessing, but through evidence.
What's Next
- Continue running Sprint 29 - Quick monitoring is validated and working
- Collect 5-10 more trades - Build the dataset for Sprint 30 tuning
- Analyze entry correlations - Find patterns that predict outcomes
- Implement Sprint 30 - With evidence-based thresholds
- A/B test - Compare win rates before/after entry timing
The goal isn't perfection. It's continuous improvement backed by data.
Building Trader-7 in public. Follow along as we turn a simple crypto trading bot into something that actually makes money.
Previous posts:
- Sprint 27: Fixing the Symbol Mismatch Bug
- Sprint 28: Activity Logs SQL Fix
- Sprint 29: Quick Monitoring Implementation
Stats as of Dec 13, 2025:
- Total trades: 57
- Win rate: 26.3%
- Current P&L: -$162.29
- System uptime: 100%