Files
trading_bot_v4/POSITION_SCALING_ROADMAP.md
mindesbunister 1e858cd25d Fix roadmap: Runner already implemented, need to optimize size & trailing stop
Corrections:
- Runner system already exists (5% with 0.3% trailing stop)
- Current +41% trade is the runner in action!
- Phase 5 reframed: Optimize runner size (5% → 10-25% for high quality) and make trailing stop ATR-based
- Updated current state and trade example to reflect actual implementation
2025-10-31 11:59:29 +01:00

14 KiB
Raw Blame History

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:
    • TP1 at +1.5%: Close 75%
    • TP2 at +3.0%: Close 80% of remaining (20% total)
    • Runner: 5% of position with 0.3% trailing stop ALREADY IMPLEMENTED
  • Problem: Small runner size (5%) + tight trailing stop (0.3%) may be suboptimal
  • 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):

-- 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)

    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)

    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: Optimize Runner Size & Trailing Stop

Prerequisites: Phase 3 complete, Runner data collected (10+ trades with runners)

Current Implementation: Runner with trailing stop already exists!

  • Runner size: 5% (configurable via TAKE_PROFIT_2_SIZE_PERCENT=80)
  • Trailing stop: 0.3% fixed (configurable via TRAILING_STOP_PERCENT=0.3)

Implementation Tasks:

  • Analyze runner performance from existing trades

    • Query trades where runner was active (TP2 hit)
    • Calculate: How many runners hit trailing stop vs kept going?
    • Calculate: Average runner profit vs optimal exit
    • Calculate: Was 0.3% trailing stop too tight? (got stopped out too early?)
  • Optimize runner size by quality tier:

    • High quality (80-100): 25% runner (TP2 closes 0%, all becomes runner)
    • Medium quality (70-79): 10% runner (TP2 closes 60% of remaining)
    • Low quality (60-69): 5% runner (current behavior)
  • Make trailing stop ATR-based:

    • Change from fixed 0.3% to (1.5 × ATR) or (2.0 × ATR)
    • Add trailingStopATRMultiplier config option
    • Update Position Manager to use ATR-based trailing distance
    • Store ATR value in ActiveTrade for dynamic calculations
  • Add runner-specific analytics:

    • Dashboard widget: Runner performance stats
    • Show: Total profit from runners vs TP1/TP2
    • Show: Average runner hold time
    • Show: Runner win rate
  • Testing:

    • Backtest: Simulate larger runners (10-25%) on historical TP2 trades
    • Backtest: Simulate ATR-based trailing stop vs fixed 0.3%
    • A/B test: Run 10 trades with optimized settings before full rollout

Expected Outcome: Capture more profit from extended moves, reduce premature trailing stop exits


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 🚀
  • Status: TP1 hit (closed 75%), TP2 hit (closed 20%), 5% runner still active with trailing stop
  • Lesson: The 5% runner captured this move! But could a larger runner (10-25%) capture even more?
  • Trailing stop: 0.3% below peak might be too tight, ATR-based (1.5-2.0×ATR) might work better

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:

-- 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