feat: add quality score display and timezone fixes
- Add qualityScore to ExecuteTradeResponse interface and response object - Update analytics page to always show Signal Quality card (N/A if unavailable) - Fix n8n workflow to pass context metrics and qualityScore to execute endpoint - Fix timezone in Telegram notifications (Europe/Berlin) - Fix symbol normalization in /api/trading/close endpoint - Update Drift ETH-PERP minimum order size (0.002 ETH not 0.01) - Add transaction confirmation to closePosition() to prevent phantom closes - Add 30-second grace period for new trades in Position Manager - Fix execution order: database save before Position Manager.addTrade() - Update copilot instructions with transaction confirmation pattern
This commit is contained in:
41
.github/copilot-instructions.md
vendored
41
.github/copilot-instructions.md
vendored
@@ -34,6 +34,7 @@ await positionManager.addTrade(activeTrade)
|
||||
- Closes positions via `closePosition()` market orders when targets hit
|
||||
- Acts as backup if on-chain orders don't fill
|
||||
- State persistence: Saves to database, restores on restart via `configSnapshot.positionManagerState`
|
||||
- **Grace period for new trades:** Skips "external closure" detection for positions <30 seconds old (Drift positions take 5-10s to propagate)
|
||||
|
||||
### 2. Drift Client (`lib/drift/client.ts`)
|
||||
**Purpose:** Solana/Drift Protocol SDK wrapper for order execution
|
||||
@@ -47,7 +48,25 @@ const health = await driftService.getAccountHealth()
|
||||
**Wallet handling:** Supports both JSON array `[91,24,...]` and base58 string formats from Phantom wallet
|
||||
|
||||
### 3. Order Placement (`lib/drift/orders.ts`)
|
||||
**Critical function:** `placeExitOrders()` - places TP/SL orders on-chain
|
||||
**Critical functions:**
|
||||
- `openPosition()` - Opens market position with transaction confirmation
|
||||
- `closePosition()` - Closes position with transaction confirmation
|
||||
- `placeExitOrders()` - Places TP/SL orders on-chain
|
||||
|
||||
**CRITICAL: Transaction Confirmation Pattern**
|
||||
Both `openPosition()` and `closePosition()` MUST confirm transactions on-chain:
|
||||
```typescript
|
||||
const txSig = await driftClient.placePerpOrder(orderParams)
|
||||
console.log('⏳ Confirming transaction on-chain...')
|
||||
const connection = driftService.getConnection()
|
||||
const confirmation = await connection.confirmTransaction(txSig, 'confirmed')
|
||||
|
||||
if (confirmation.value.err) {
|
||||
throw new Error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`)
|
||||
}
|
||||
console.log('✅ Transaction confirmed on-chain')
|
||||
```
|
||||
Without this, the SDK returns signatures for transactions that never execute, causing phantom trades/closes.
|
||||
|
||||
**Dual Stop System** (USE_DUAL_STOPS=true):
|
||||
```typescript
|
||||
@@ -253,7 +272,7 @@ docker exec trading-bot-postgres psql -U postgres -d trading_bot_v4 -c "\dt"
|
||||
|
||||
2. **Wrong DATABASE_URL:** Container runtime needs `trading-bot-postgres`, Prisma CLI from host needs `localhost:5432`
|
||||
|
||||
3. **Symbol format mismatch:** Always normalize with `normalizeTradingViewSymbol()` before calling Drift
|
||||
3. **Symbol format mismatch:** Always normalize with `normalizeTradingViewSymbol()` before calling Drift (applies to ALL endpoints including `/api/trading/close`)
|
||||
|
||||
4. **Missing reduce-only flag:** Exit orders without `reduceOnly: true` can accidentally open new positions
|
||||
|
||||
@@ -268,6 +287,24 @@ docker exec trading-bot-postgres psql -U postgres -d trading_bot_v4 -c "\dt"
|
||||
- `TAKE_PROFIT_2_SIZE_PERCENT=80` means "close 80% of REMAINING" (not of original)
|
||||
- Actual runner size = (100 - TP1%) × (100 - TP2%) / 100 = 5% with defaults
|
||||
|
||||
9. **Transaction confirmation CRITICAL:** Both `openPosition()` AND `closePosition()` MUST call `connection.confirmTransaction()` after `placePerpOrder()`. Without this, the SDK returns transaction signatures that aren't confirmed on-chain, causing "phantom trades" or "phantom closes". Always check `confirmation.value.err` before proceeding.
|
||||
|
||||
10. **Execution order matters:** When creating trades via API endpoints, the order MUST be:
|
||||
1. Open position + place exit orders
|
||||
2. Save to database (`createTrade()`)
|
||||
3. Add to Position Manager (`positionManager.addTrade()`)
|
||||
|
||||
If Position Manager is added before database save, race conditions occur where monitoring checks before the trade exists in DB.
|
||||
|
||||
11. **New trade grace period:** Position Manager skips "external closure" detection for trades <30 seconds old because Drift positions take 5-10 seconds to propagate after opening. Without this grace period, new positions are immediately detected as "closed externally" and cancelled.
|
||||
|
||||
12. **Drift minimum position sizes:** Actual minimums differ from documentation:
|
||||
- SOL-PERP: 0.1 SOL (~$5-15 depending on price)
|
||||
- ETH-PERP: 0.002 ETH (~$7-8 at $4000/ETH) - NOT 0.01 ETH
|
||||
- BTC-PERP: 0.0001 BTC (~$10-12 at $100k/BTC)
|
||||
|
||||
Always calculate: `minOrderSize × currentPrice` must exceed Drift's $4 minimum. Add buffer for price movement.
|
||||
|
||||
## File Conventions
|
||||
|
||||
- **API routes:** `app/api/[feature]/[action]/route.ts` (Next.js 15 App Router)
|
||||
|
||||
Reference in New Issue
Block a user