docs: Add Common Pitfall #44 - Breakeven SL price discrepancy

Documents the fix for breakeven SL using database entry price instead of
Drift's actual on-chain entry price.

Issue: Database stored $139.18 but Drift actual was $139.07, causing
'breakeven' SL to lock in $0.11 loss per token for SHORT positions.

Solution: Query position.entryPrice from Drift SDK (calculated from
on-chain quoteAssetAmount / baseAssetAmount) when setting breakeven.

Includes real incident details, code comparison, and relationship to
Common Pitfall #33 (orphaned position restoration).

Related commit: 528a0f4
This commit is contained in:
mindesbunister
2025-11-16 01:45:48 +01:00
parent 528a0f4f43
commit 56b2195b88

View File

@@ -1874,6 +1874,38 @@ trade.realizedPnL += actualRealizedPnL // NOT: result.realizedPnL from SDK
- **Drift documentation:** Account leverage must be set in UI, is persistent on-chain setting - **Drift documentation:** Account leverage must be set in UI, is persistent on-chain setting
- **Lesson:** On-chain account settings cannot be changed via API - always verify account state matches bot assumptions before production trading - **Lesson:** On-chain account settings cannot be changed via API - always verify account state matches bot assumptions before production trading
44. **Breakeven SL using database entry price instead of Drift's actual entry (Fixed Nov 16, 2025):**
- **Symptom:** After TP1 hits, SL moved to "breakeven" but at wrong price - SHORT with $139.07 entry gets SL at $139.18 ($0.11 loss if hit)
- **Root Cause:** Position Manager used `trade.entryPrice` from database, which can differ from Drift's actual fill price by $0.10-0.15
- **Price discrepancy sources:**
* Database stores initial expected price
* Drift fills at market price (slippage)
* Orphaned position restorations use stale database price (see Common Pitfall #33)
* Oracle price delays during execution
- **Real incident (Nov 16, 01:37 CET):**
* User screenshot: Entry $139.07, SL $139.18, Current $138.58
* Database: entryPrice=$139.18291
* Drift UI: Entry Price=$139.07
* Discrepancy: $0.11 (would lose money if SL hit on "breakeven")
- **Impact:** Breakeven SL not truly breakeven - gives back profit or locks in unnecessary loss
- **Fix:** Query Drift SDK for actual entry price when setting breakeven SL
```typescript
// In lib/trading/position-manager.ts (line ~511):
// BEFORE:
trade.stopLossPrice = trade.entryPrice // Uses database value
// AFTER:
const actualEntryPrice = position.entryPrice || trade.entryPrice
console.log(`📊 Breakeven calculation: DB entry=$${trade.entryPrice.toFixed(4)}, Drift entry=$${actualEntryPrice.toFixed(4)}`)
trade.stopLossPrice = actualEntryPrice // Uses Drift's on-chain calculated price
```
- **Drift SDK accuracy:** `position.entryPrice` calculated from on-chain data (quoteAssetAmount / baseAssetAmount) = authoritative
- **Fallback:** If position.entryPrice unavailable, falls back to database entry (rare edge case)
- **Logging:** Now shows both DB and Drift entry prices for verification
- **Related issues:** Common Pitfall #33 (orphaned position restoration with wrong entry)
- **Git commit:** 528a0f4 "fix: Use Drift's actual entry price for breakeven SL"
- **Lesson:** For critical price calculations (breakeven, TP, SL), always prefer on-chain data over cached database values
## File Conventions ## File Conventions
- **API routes:** `app/api/[feature]/[action]/route.ts` (Next.js 15 App Router) - **API routes:** `app/api/[feature]/[action]/route.ts` (Next.js 15 App Router)