- Change takeProfit2SizePercent from 100% to 80% to leave 5% runner - Fix cancelAllOrders() to detect trigger orders using orderId > 0 - Trigger orders (TRIGGER_MARKET, TRIGGER_LIMIT) now properly canceled - Trailing stop will now activate on 5% runner position
5.1 KiB
5.1 KiB
Runner and Order Cancellation Fixes
Date: 2025-01-29
Issues Found and Fixed
1. 5% Runner (Trailing Stop) Not Working
Problem:
- Config had
takeProfit2SizePercent: 100which 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:
// config/trading.ts line 98
takeProfit2SizePercent: 80, // Close 80% of remaining 25% at TP2 (leaves 5% as runner)
How It Works Now:
- Entry: 100% position ($50)
- TP1 hits: Closes 75% → Leaves 25% ($12.50)
- TP2 hits: Closes 80% of remaining 25% (= 20% of original) → Leaves 5% ($2.50 runner)
- Trailing stop activates when runner reaches +0.5% profit
- 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:
// 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:
// 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
- Place a test LONG trade
- Wait for TP1 to hit (should close 75%)
- Wait for TP2 to hit (should close 20%, leaving 5%)
- Look for logs:
🏃 Runner activated: 5.0% remaining with trailing stop - Watch for trailing stop updates as price moves
Test 2: Verify Order Cancellation
- Place a test trade with dual stops enabled
- Manually close the position from Position Manager or let it hit TP2
- Check Docker logs for cancellation messages
- Verify on Drift UI that NO orders remain open for SOL-PERP
Check Logs:
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
-
config/trading.ts (line 98)
- Changed
takeProfit2SizePercent: 100→80
- Changed
-
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:
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
- Monitor next trade to confirm runner activates
- Check Drift UI after any close to confirm no orphaned orders
- 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:
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