Update copilot-instructions with critical Drift SDK insights
- Document Drift SDK position.size returns USD, not token quantity - Add Solana RPC rate limiting retry pattern with exponential backoff - Document /api/trading/cancel-orders endpoint for ghost order cleanup - Clarify symbol normalization requirement for manual close endpoint - Captures lessons learned from TP1 detection and P&L calculation debugging
This commit is contained in:
44
.github/copilot-instructions.md
vendored
44
.github/copilot-instructions.md
vendored
@@ -136,6 +136,7 @@ const health = await driftService.getAccountHealth()
|
||||
- `openPosition()` - Opens market position with transaction confirmation
|
||||
- `closePosition()` - Closes position with transaction confirmation
|
||||
- `placeExitOrders()` - Places TP/SL orders on-chain
|
||||
- `cancelAllOrders()` - Cancels all reduce-only orders for a market
|
||||
|
||||
**CRITICAL: Transaction Confirmation Pattern**
|
||||
Both `openPosition()` and `closePosition()` MUST confirm transactions on-chain:
|
||||
@@ -152,6 +153,46 @@ console.log('✅ Transaction confirmed on-chain')
|
||||
```
|
||||
Without this, the SDK returns signatures for transactions that never execute, causing phantom trades/closes.
|
||||
|
||||
**CRITICAL: Drift SDK position.size is USD, not tokens**
|
||||
The Drift SDK returns `position.size` as USD notional value, NOT token quantity:
|
||||
```typescript
|
||||
// WRONG: Multiply by price (inflates by 156x for SOL at $157)
|
||||
const positionSizeUSD = position.size * currentPrice
|
||||
|
||||
// CORRECT: Use directly as USD value
|
||||
const positionSizeUSD = Math.abs(position.size)
|
||||
```
|
||||
This affects Position Manager's TP1 detection - if calculated incorrectly, TP1 will never trigger because expected size won't match actual size.
|
||||
|
||||
**Solana RPC Rate Limiting with Exponential Backoff**
|
||||
Solana RPC endpoints return 429 errors under load. Always use retry logic for order operations:
|
||||
```typescript
|
||||
export async function retryWithBackoff<T>(
|
||||
operation: () => Promise<T>,
|
||||
maxRetries: number = 3,
|
||||
initialDelay: number = 2000
|
||||
): Promise<T> {
|
||||
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
||||
try {
|
||||
return await operation()
|
||||
} catch (error: any) {
|
||||
if (error?.message?.includes('429') && attempt < maxRetries - 1) {
|
||||
const delay = initialDelay * Math.pow(2, attempt)
|
||||
console.log(`⏳ Rate limited, retrying in ${delay/1000}s... (attempt ${attempt + 1}/${maxRetries})`)
|
||||
await new Promise(resolve => setTimeout(resolve, delay))
|
||||
continue
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
throw new Error('Max retries exceeded')
|
||||
}
|
||||
|
||||
// Usage in cancelAllOrders
|
||||
await retryWithBackoff(() => driftClient.cancelOrders(...))
|
||||
```
|
||||
Without this, order cancellations fail silently during TP1→breakeven order updates, leaving ghost orders that cause incorrect fills.
|
||||
|
||||
**Dual Stop System** (USE_DUAL_STOPS=true):
|
||||
```typescript
|
||||
// Soft stop: TRIGGER_LIMIT at -1.5% (avoids wicks)
|
||||
@@ -233,7 +274,8 @@ const driftSymbol = normalizeTradingViewSymbol(body.symbol)
|
||||
- `/api/trading/execute` - Main entry point from n8n (production, requires auth), **auto-caches market data**
|
||||
- `/api/trading/check-risk` - Pre-execution validation (duplicate check, quality score, **per-symbol cooldown**, rate limits, **symbol enabled check**)
|
||||
- `/api/trading/test` - Test trades from settings UI (no auth required, **respects symbol enable/disable**)
|
||||
- `/api/trading/close` - Manual position closing
|
||||
- `/api/trading/close` - Manual position closing (requires symbol normalization)
|
||||
- `/api/trading/cancel-orders` - **Manual order cleanup** (for stuck/ghost orders after rate limit failures)
|
||||
- `/api/trading/positions` - Query open positions from Drift
|
||||
- `/api/trading/market-data` - Webhook for TradingView market data updates (GET for debug, POST for data)
|
||||
- `/api/settings` - Get/update config (writes to .env file, **includes per-symbol settings**)
|
||||
|
||||
Reference in New Issue
Block a user