docs: document flip-flop price data bug and fix
Updated documentation to reflect critical bug found and fixed:
SIGNAL_QUALITY_OPTIMIZATION_ROADMAP.md:
- Added bug fix commit (795026a) to Phase 1.5
- Documented price source (Pyth price monitor)
- Added validation and logging details
- Included Known Issues section with real incident details
- Updated monitoring examples with detailed price logging
.github/copilot-instructions.md:
- Added Common Pitfall #31: Flip-flop price context bug
- Documented root cause: currentPrice undefined in check-risk
- Real incident: Nov 14 06:05, -$1.56 loss from false positive
- Two-part fix with code examples (price fetch + validation)
- Lesson: Always validate financial calculation inputs
- Monitoring guidance: Watch for flip-flop price check logs
This ensures future AI agents and developers understand:
1. Why Pyth price fetch is needed in check-risk
2. Why validation before calculation is critical
3. The real financial impact of missing validation
This commit is contained in:
38
.github/copilot-instructions.md
vendored
38
.github/copilot-instructions.md
vendored
@@ -1138,6 +1138,44 @@ trade.realizedPnL += actualRealizedPnL // NOT: result.realizedPnL from SDK
|
||||
- **Impact:** Protects user from unlimited risk during unavailable hours. Phantom trades are rare edge cases (oracle issues, exchange rejections).
|
||||
- **Database tracking:** `status='phantom'`, `exitReason='manual'`, enables analysis of phantom frequency and patterns
|
||||
|
||||
31. **Flip-flop price context using wrong data (CRITICAL - Fixed Nov 14, 2025):**
|
||||
- **Symptom:** Flip-flop detection showing "100% price move" when actual movement was 0.2%, allowing trades that should be blocked
|
||||
- **Root Cause:** `currentPrice` parameter not available in check-risk endpoint (trade hasn't opened yet), so calculation used undefined/zero
|
||||
- **Real incident:** Nov 14, 06:05 CET - SHORT allowed with 0.2% flip-flop, lost -$1.56 in 5 minutes
|
||||
- **Bug sequence:**
|
||||
1. LONG opened at $143.86 (06:00)
|
||||
2. SHORT signal 4min later at $143.58 (0.2% move)
|
||||
3. Flip-flop check: `(undefined - 143.86) / 143.86 * 100` = garbage → showed "100%"
|
||||
4. System thought it was reversal → allowed trade
|
||||
5. Should have been blocked as tight-range chop
|
||||
- **Fix:** Two-part fix in commits 77a9437 and 795026a:
|
||||
```typescript
|
||||
// In app/api/trading/check-risk/route.ts:
|
||||
// Get current price from Pyth BEFORE quality scoring
|
||||
const priceMonitor = getPythPriceMonitor()
|
||||
const latestPrice = priceMonitor.getCachedPrice(body.symbol)
|
||||
const currentPrice = latestPrice?.price || body.currentPrice
|
||||
|
||||
// In lib/trading/signal-quality.ts:
|
||||
// Validate price data exists before calculation
|
||||
if (!params.currentPrice || params.currentPrice === 0) {
|
||||
// No current price available - apply penalty (conservative)
|
||||
console.warn(`⚠️ Flip-flop check: No currentPrice available, applying penalty`)
|
||||
frequencyPenalties.flipFlop = -25
|
||||
score -= 25
|
||||
} else {
|
||||
const priceChangePercent = Math.abs(
|
||||
(params.currentPrice - recentSignals.oppositeDirectionPrice) /
|
||||
recentSignals.oppositeDirectionPrice * 100
|
||||
)
|
||||
console.log(`🔍 Flip-flop price check: $${recentSignals.oppositeDirectionPrice.toFixed(2)} → $${params.currentPrice.toFixed(2)} = ${priceChangePercent.toFixed(2)}%`)
|
||||
// Apply penalty only if < 2% move
|
||||
}
|
||||
```
|
||||
- **Impact:** Without this fix, flip-flop detection is useless - blocks reversals, allows chop
|
||||
- **Lesson:** Always validate input data for financial calculations, especially when data might not exist yet
|
||||
- **Monitoring:** Watch logs for "🔍 Flip-flop price check: $X → $Y = Z%" to verify correct calculations
|
||||
|
||||
## File Conventions
|
||||
|
||||
- **API routes:** `app/api/[feature]/[action]/route.ts` (Next.js 15 App Router)
|
||||
|
||||
Reference in New Issue
Block a user