# Runner and Order Cancellation Fixes ## Date: 2025-01-29 ## Issues Found and Fixed ### 1. **5% Runner (Trailing Stop) Not Working** **Problem:** - Config had `takeProfit2SizePercent: 100` which closed 100% of remaining position at TP2 - This left 0% for the runner, so trailing stop never activated - Logs showed "Executing TP2 for SOL-PERP (80%)" but no "Runner activated" messages **Root Cause:** - After TP1 closes 75%, remaining position is 25% - TP2 at 100% closes all of that 25%, leaving nothing for trailing stop **Fix Applied:** ```typescript // config/trading.ts line 98 takeProfit2SizePercent: 80, // Close 80% of remaining 25% at TP2 (leaves 5% as runner) ``` **How It Works Now:** 1. Entry: 100% position ($50) 2. TP1 hits: Closes 75% → Leaves 25% ($12.50) 3. TP2 hits: Closes 80% of remaining 25% (= 20% of original) → Leaves 5% ($2.50 runner) 4. Trailing stop activates when runner reaches +0.5% profit 5. Stop loss trails 0.3% below peak price **Expected Behavior:** - You should now see: `🏃 Runner activated: 5.0% remaining with trailing stop` - Then: `📈 Trailing SL updated: $X.XX → $Y.YY (0.3% below peak $Z.ZZ)` - Finally: `🔴 TRAILING STOP HIT: SOL-PERP at +X.XX%` --- ### 2. **Stop-Loss Orders Not Being Canceled After Position Closes** **Problem:** - When position closed (by software or on-chain orders), 2 SL orders remained open on Drift - Drift UI showed orphaned TRIGGER_MARKET and TRIGGER_LIMIT orders - Logs showed "Position fully closed, cancelling remaining orders..." but NO "Cancelled X orders" **Root Cause:** ```typescript // OLD CODE - lib/drift/orders.ts line 570 const ordersToCancel = userAccount.orders.filter( (order: any) => order.marketIndex === marketConfig.driftMarketIndex && order.status === 0 // ❌ WRONG: Trigger orders have different status values ) ``` The filter `order.status === 0` only caught LIMIT orders in "open" state, but missed: - **TRIGGER_MARKET** orders (hard stop loss) - **TRIGGER_LIMIT** orders (soft stop loss) These trigger orders have different status enum values in Drift SDK. **Fix Applied:** ```typescript // NEW CODE - lib/drift/orders.ts line 569-573 const ordersToCancel = userAccount.orders.filter( (order: any) => order.marketIndex === marketConfig.driftMarketIndex && order.orderId > 0 // ✅ Active orders have orderId > 0 (catches ALL types) ) ``` **Why This Works:** - All active orders (LIMIT, TRIGGER_MARKET, TRIGGER_LIMIT) have `orderId > 0` - Inactive/cancelled orders have `orderId = 0` - This catches trigger orders regardless of their status enum value **Expected Behavior:** - When position closes, you should now see: ``` 🗑️ Position fully closed, cancelling remaining orders... 📋 Found 2 open orders to cancel (including trigger orders) ✅ Orders cancelled! Transaction: 5x7Y8z... ✅ Cancelled 2 orders ``` --- ## Testing Recommendations ### Test 1: Verify Runner Activation 1. Place a test LONG trade 2. Wait for TP1 to hit (should close 75%) 3. Wait for TP2 to hit (should close 20%, leaving 5%) 4. Look for logs: `🏃 Runner activated: 5.0% remaining with trailing stop` 5. Watch for trailing stop updates as price moves ### Test 2: Verify Order Cancellation 1. Place a test trade with dual stops enabled 2. Manually close the position from Position Manager or let it hit TP2 3. Check Docker logs for cancellation messages 4. Verify on Drift UI that NO orders remain open for SOL-PERP **Check Logs:** ```bash docker logs trading-bot-v4 -f | grep -E "(Runner|Trailing|Cancelled|open orders)" ``` **Check Drift Orders:** Go to https://app.drift.trade/ → Orders tab → Should show 0 open orders after close --- ## Files Modified 1. **config/trading.ts** (line 98) - Changed `takeProfit2SizePercent: 100` → `80` 2. **lib/drift/orders.ts** (lines 569-573, 579) - Fixed order filtering to catch trigger orders - Changed `order.status === 0` → `order.orderId > 0` - Updated log message to mention trigger orders --- ## Docker Deployment Changes deployed via: ```bash docker compose build trading-bot docker compose up -d --force-recreate trading-bot ``` Container restarted successfully at: 2025-01-29 (timestamp in logs) --- ## Next Steps 1. **Monitor next trade** to confirm runner activates 2. **Check Drift UI** after any close to confirm no orphaned orders 3. **Adjust trailing stop settings** if needed: - `trailingStopPercent: 0.3` (current: trail 0.3% below peak) - `trailingStopActivation: 0.5` (current: activate at +0.5% profit) --- ## Related Configuration Current trailing stop settings in `config/trading.ts`: ```typescript useTrailingStop: true, // Enable trailing stop trailingStopPercent: 0.3, // Trail 0.3% below peak trailingStopActivation: 0.5, // Activate at +0.5% profit takeProfit1SizePercent: 75, // TP1: Close 75% takeProfit2SizePercent: 80, // TP2: Close 80% of remaining (= 20% total) // Runner: 5% remains ``` **Math:** - Entry: 100% ($50 position) - After TP1: 25% remains ($12.50) - After TP2: 25% × (100% - 80%) = 5% remains ($2.50) - Runner: 5% with trailing stop