- 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
163 lines
5.1 KiB
Markdown
163 lines
5.1 KiB
Markdown
# 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
|