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:
32
.github/copilot-instructions.md
vendored
32
.github/copilot-instructions.md
vendored
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user