Files
trading_bot_v4/POSITION_SCALING_ROADMAP.md
mindesbunister 9989f75955 Add position scaling & exit optimization roadmap
- 6-phase development plan: data collection → ATR-based → quality tiers → direction bias → runners → ML
- Each phase has clear prerequisites, implementation tasks, and success criteria
- Decision gates based on data validation (20+ trades for Phase 2, 30+ for Phase 3, etc.)
- Includes SQL queries for analysis and performance validation
- Documents current +41% trade as motivation for runner implementation
- Estimated 3-4 months timeline to complete Phases 1-5
2025-10-31 11:55:34 +01:00

382 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Position Scaling & Exit Optimization Roadmap
## Current State (October 31, 2025)
- **Total Trades:** 26 completed
- **P&L:** +$27.12 (38% win rate)
- **Shorts:** 6.6x more profitable than longs (+$2.46 vs -$0.37 avg)
- **Current Strategy:** 75% at TP1 (+1.5%), 25% at TP2 (+3%), no runner
- **Problem:** Missed +41% move (would've closed at +3%)
- **Data Quality:** Ready to collect signal quality scores for correlation analysis
---
## Phase 1: Data Collection (CURRENT PHASE) 🔄
**Goal:** Gather 20-50 trades with quality scores before making strategy changes
### Data Points to Track:
- [ ] Signal quality score (0-100) for each trade
- [ ] Max Favorable Excursion (MFE) vs exit price differential
- [ ] ATR at entry vs actual price movement distance
- [ ] Time duration for winning trades (identify "quick wins" vs "runners")
- [ ] Quality score correlation with:
- [ ] Win rate
- [ ] Average P&L
- [ ] MFE (runner potential)
- [ ] Trade duration
### Analysis Queries (Run after 20+ scored trades):
```sql
-- Quality score vs performance
SELECT
CASE
WHEN "signalQualityScore" >= 80 THEN 'High (80-100)'
WHEN "signalQualityScore" >= 70 THEN 'Medium (70-79)'
ELSE 'Low (60-69)'
END as quality_tier,
COUNT(*) as trades,
ROUND(AVG("realizedPnL")::numeric, 2) as avg_pnl,
ROUND(AVG("maxFavorableExcursion")::numeric, 2) as avg_mfe,
ROUND(100.0 * SUM(CASE WHEN "realizedPnL" > 0 THEN 1 ELSE 0 END) / COUNT(*)::numeric, 1) as win_rate
FROM "Trade"
WHERE "signalQualityScore" IS NOT NULL AND "exitReason" IS NOT NULL
GROUP BY quality_tier
ORDER BY quality_tier;
-- ATR correlation with movement
SELECT
direction,
ROUND(AVG(atr)::numeric, 2) as avg_atr,
ROUND(AVG("maxFavorableExcursion")::numeric, 2) as avg_mfe,
ROUND(AVG(ABS("exitPrice" - "entryPrice") / "entryPrice" * 100)::numeric, 2) as avg_move_pct
FROM "Trade"
WHERE atr IS NOT NULL AND "exitReason" IS NOT NULL
GROUP BY direction;
-- Runner potential analysis (how many went beyond TP2?)
SELECT
"exitReason",
COUNT(*) as count,
ROUND(AVG("maxFavorableExcursion")::numeric, 2) as avg_mfe,
ROUND(AVG("realizedPnL")::numeric, 2) as avg_pnl,
-- MFE > 3% indicates runner potential
SUM(CASE WHEN "maxFavorableExcursion" > 3.0 THEN 1 ELSE 0 END) as runner_potential_count
FROM "Trade"
WHERE "exitReason" IS NOT NULL
GROUP BY "exitReason"
ORDER BY count DESC;
```
---
## Phase 2: ATR-Based Dynamic Targets ⏳
**Prerequisites:** ✅ 20+ trades with ATR data collected
### Implementation Tasks:
- [ ] **Add ATR normalization function** (`lib/trading/scaling-strategy.ts`)
- [ ] Calculate normalized ATR factor: `(current_ATR / baseline_ATR)`
- [ ] Baseline ATR = 2.0 for SOL-PERP (adjust based on data)
- [ ] **Update TP calculation in `lib/drift/orders.ts`**
- [ ] TP1: `entry + (1.5% × ATR_factor)` instead of fixed 1.5%
- [ ] TP2: `entry + (3.0% × ATR_factor)` instead of fixed 3.0%
- [ ] **Modify Position Manager monitoring loop**
- [ ] Store `atrFactor` in `ActiveTrade` interface
- [ ] Adjust dynamic SL movements by ATR factor
- [ ] Update breakeven trigger: `+0.5% × ATR_factor`
- [ ] Update profit lock trigger: `+1.2% × ATR_factor`
- [ ] **Testing:**
- [ ] Backtest on historical trades with ATR data
- [ ] Calculate improvement: old fixed % vs new ATR-adjusted
- [ ] Run 10 test trades before production
**Expected Outcome:** Wider targets in high volatility, tighter in low volatility
---
## Phase 3: Signal Quality-Based Scaling ⏳
**Prerequisites:** ✅ Phase 2 complete, ✅ 30+ trades with quality scores, ✅ Clear correlation proven
### Implementation Tasks:
- [ ] **Create quality tier configuration** (`config/trading.ts`)
```typescript
export interface QualityTierConfig {
minScore: number
maxScore: number
tp1Percentage: number // How much to take off
tp2Percentage: number
runnerPercentage: number
atrMultiplierTP1: number
atrMultiplierTP2: number
trailingStopATR: number
}
```
- [ ] **Define three tiers based on data analysis:**
- [ ] **High Quality (80-100):** Aggressive runner strategy
- TP1: 50% off at 2.0×ATR
- TP2: 25% off at 4.0×ATR
- Runner: 25% with 2.5×ATR trailing stop
- [ ] **Medium Quality (70-79):** Balanced (current-ish)
- TP1: 75% off at 1.5×ATR
- TP2: 25% off at 3.0×ATR
- Runner: None (full exit at TP2)
- [ ] **Low Quality (60-69):** Conservative quick exit
- TP1: 100% off at 1.0×ATR
- TP2: None
- Runner: None
- [ ] **Update `placeExitOrders()` function**
- [ ] Accept `qualityScore` parameter
- [ ] Select tier config based on score
- [ ] Place orders according to tier rules
- [ ] Only place TP2 order if tier has runner
- [ ] **Update Position Manager**
- [ ] Store `qualityScore` in `ActiveTrade`
- [ ] Apply tier-specific trailing stop logic
- [ ] Handle partial closes (50%, 75%, or 100%)
- [ ] **Database tracking:**
- [ ] Add `scalingTier` field to Trade model (high/medium/low)
- [ ] Track which tier was used for each trade
**Expected Outcome:** High quality signals let winners run, low quality signals take quick profits
---
## Phase 4: Direction-Based Optimization ⏳
**Prerequisites:** ✅ Phase 3 complete, ✅ Directional edge confirmed in 50+ trades
### Implementation Tasks:
- [ ] **Analyze directional performance** (Re-run after 50 trades)
- [ ] Compare long vs short win rates
- [ ] Compare long vs short avg P&L
- [ ] Compare long vs short MFE (runner potential)
- [ ] **Decision:** If shorts still 3x+ better, implement direction bias
- [ ] **Direction-specific configs** (`config/trading.ts`)
```typescript
export interface DirectionConfig {
shortTP1Pct: number // If shorts have edge, wider targets
shortTP2Pct: number
shortRunnerPct: number
longTP1Pct: number // If longs struggle, tighter defensive
longTP2Pct: number
longRunnerPct: number
}
```
- [ ] **Implementation in order placement:**
- [ ] Check `direction` field
- [ ] Apply direction-specific multipliers on top of quality tier
- [ ] Example: Short with high quality = 2.0×ATR × 1.2 (direction bonus)
- [ ] **A/B Testing:**
- [ ] Run 20 trades with direction bias
- [ ] Run 20 trades without (control group)
- [ ] Compare results before full rollout
**Expected Outcome:** Shorts get wider targets if edge persists, longs stay defensive
---
## Phase 5: Runner with Trailing Stop ⏳
**Prerequisites:** ✅ Phase 3 complete, ✅ Runner potential confirmed (MFE > TP2 in 30%+ of trades)
### Implementation Tasks:
- [ ] **Add trailing stop logic to Position Manager**
- [ ] Track `peakPrice` for runner portion
- [ ] Update `peakPrice` when current price exceeds it
- [ ] Calculate trailing stop distance: `peakPrice - (trailingStopATR × ATR)`
- [ ] Close runner when price crosses trailing stop
- [ ] **Modify `checkTargets()` function:**
- [ ] After TP2 hit, activate `trailingStopActive = true`
- [ ] Monitor runner separately from main position
- [ ] Close runner with `closePosition()` when trailing stop breached
- [ ] **Add runner tracking to database:**
- [ ] `runnerSize` field (amount left after TP2)
- [ ] `runnerPeakPrice` field
- [ ] `runnerExitPrice` field
- [ ] `runnerExitReason` field ('trailing_stop', 'manual', etc.)
- [ ] **Testing:**
- [ ] Backtest: Simulate runners on TP2 trades
- [ ] Calculate: How much extra profit would runners have captured?
- [ ] Test with small position sizes first ($10-20)
- [ ] **Edge case handling:**
- [ ] What if runner goes negative after TP2? (Move SL to breakeven on runner)
- [ ] What if bot restarts with active runner? (Restore from database)
- [ ] What if on-chain runner order fails? (Position Manager backup)
**Expected Outcome:** Capture extended moves like the +41% trade that's currently open
---
## Phase 6: Advanced ML-Based Exit Prediction (Future) 🔮
**Prerequisites:** ✅ 100+ trades with all metrics, ✅ Phases 1-5 complete
### Research Tasks:
- [ ] **Feature engineering:**
- [ ] Input features: ATR, ADX, RSI, volumeRatio, pricePosition, quality score, direction, timeframe
- [ ] Target variable: Did trade reach 2×TP2? (binary classification)
- [ ] Additional target: Max profit % reached (regression)
- [ ] **Model training:**
- [ ] Split data: 70% train, 30% test
- [ ] Try models: Logistic Regression, Random Forest, XGBoost
- [ ] Evaluate: Precision, Recall, F1 for runner prediction
- [ ] Cross-validation with time-based splits (avoid lookahead bias)
- [ ] **Integration:**
- [ ] `/api/trading/predict-runner` endpoint
- [ ] Call during trade execution to get runner probability
- [ ] Adjust runner size based on probability: 0-15% runner if low, 25-35% if high
- [ ] **Monitoring:**
- [ ] Track model accuracy over time
- [ ] Retrain monthly with new data
- [ ] A/B test: ML-based vs rule-based scaling
**Expected Outcome:** AI predicts which trades have runner potential before entry
---
## Quick Wins (Can Do Anytime) ⚡
- [ ] **Manual runner management for current trade**
- [ ] Move SL to +30% profit lock on current +41% SOL position
- [ ] Monitor manually until trend breaks
- [ ] Document outcome: How much did runner capture?
- [ ] **Add "runner stats" to analytics dashboard**
- [ ] Show: How many trades went beyond TP2?
- [ ] Show: Average MFE for TP2 exits
- [ ] Show: Estimated missed profit from not having runners
- [ ] **Database views for common queries**
- [ ] Create `vw_quality_performance` view
- [ ] Create `vw_runner_potential` view
- [ ] Create `vw_directional_edge` view
- [ ] **Alerts for exceptional trades**
- [ ] Telegram notification when MFE > 5% (runner candidate)
- [ ] Telegram notification when quality score > 90 (premium setup)
---
## Decision Gates 🚦
**Before Phase 2 (ATR-based):**
- ✅ Have 20+ trades with ATR data
- ✅ ATR values look reasonable (0.5 - 3.5 range)
- ✅ Clear volatility variation observed
**Before Phase 3 (Quality tiers):**
- ✅ Have 30+ trades with quality scores
- ✅ Statistical significance: High quality scores show measurably better outcomes
- ✅ Correlation coefficient > 0.3 between quality and P&L
**Before Phase 4 (Direction bias):**
- ✅ Have 50+ trades (25+ each direction)
- ✅ Directional edge persists (3x+ performance gap)
- ✅ Edge is consistent across different market conditions
**Before Phase 5 (Runners):**
- ✅ 30%+ of trades show MFE > TP2
- ✅ Average MFE significantly higher than TP2 level
- ✅ Phases 2-3 stable and profitable
**Before Phase 6 (ML):**
- ✅ 100+ trades with complete feature data
- ✅ Proven improvement from Phases 1-5
- ✅ Computational resources available (training time)
---
## Notes & Observations
### Current Trade Example (Oct 31, 2025):
- Entry: $182.73
- Current: $186.56 (+2.1%, +$11.30)
- **Actual P&L: +41% unrealized** 🚀
- Current strategy would've closed at +3% ($16.20)
- **Missed profit: ~$59** if this hits +41% realized
- **Lesson:** Need runner implementation ASAP once data supports it
### Key Metrics to Watch:
- Win rate by quality tier
- Average MFE vs exit price gap
- Correlation between ATR and price movement
- Shorts vs longs performance delta
- Percentage of trades that go beyond TP2
### Strategy Validation:
Run this after each phase to validate improvement:
```sql
-- Compare old vs new strategy performance
SELECT
'Phase X' as phase,
COUNT(*) as trades,
ROUND(AVG("realizedPnL")::numeric, 2) as avg_pnl,
ROUND(SUM("realizedPnL")::numeric, 2) as total_pnl,
ROUND(100.0 * SUM(CASE WHEN "realizedPnL" > 0 THEN 1 ELSE 0 END) / COUNT(*)::numeric, 1) as win_rate
FROM "Trade"
WHERE "createdAt" >= '[phase_start_date]'
AND "exitReason" IS NOT NULL;
```
---
## Timeline Estimate
- **Phase 1 (Data Collection):** 2-4 weeks (depends on signal frequency)
- **Phase 2 (ATR-based):** 3-5 days implementation + 1 week testing
- **Phase 3 (Quality tiers):** 5-7 days implementation + 2 weeks testing
- **Phase 4 (Direction bias):** 2-3 days implementation + 1 week testing
- **Phase 5 (Runners):** 7-10 days implementation + 2 weeks testing
- **Phase 6 (ML):** 2-3 weeks research + implementation
**Total estimated time:** 3-4 months from start to Phase 5 complete
---
## Success Criteria
**Phase 2 Success:**
- [ ] Average P&L increases by 10%+ vs fixed targets
- [ ] Win rate stays stable or improves
- [ ] No increase in max drawdown
**Phase 3 Success:**
- [ ] High quality trades show 20%+ better P&L than low quality
- [ ] Overall P&L increases by 15%+ vs Phase 2
- [ ] Quality filtering prevents some losing trades
**Phase 4 Success:**
- [ ] Directional P&L gap narrows (improve weak direction)
- [ ] Or: Strong direction P&L improves further (if edge is real)
**Phase 5 Success:**
- [ ] Runners capture 20%+ more profit on winning trades
- [ ] Total P&L increases by 25%+ vs Phase 4
- [ ] Runners don't create new losing trades
**Overall Success (All Phases):**
- [ ] 2x total P&L vs baseline strategy
- [ ] 50%+ win rate (up from 38%)
- [ ] Average winner > 2× average loser
- [ ] Profit factor > 2.0
---
**Status:** Phase 1 (Data Collection) - Active 🔄
**Last Updated:** October 31, 2025
**Next Review:** After 20 trades with quality scores collected