From 0f88d88dd3b7b668c9010ba43cc8517476eb934d Mon Sep 17 00:00:00 2001 From: mindesbunister Date: Wed, 3 Dec 2025 10:27:07 +0100 Subject: [PATCH] docs: Add Common Pitfalls #68-69 (Dec 3, 2025 bug fixes) - Pitfall #68: Smart Entry using webhook percentage as signal price * Root cause: TradingView webhook price field contained percentage (70.80) instead of market price (42.50) * Impact: 97% pullback calculations made Smart Entry impossible to trigger * Fix: Use Pyth current price instead of webhook price * Commit: 7d0d38a - Pitfall #69: Direction-specific leverage thresholds not explicit * Made LONG/SHORT leverage assignment explicit even though values same * Improves code clarity and maintainability * Commit: 58f812f Both fixes deployed Dec 3, 2025, 09:02:45 CET (timestamp verified) --- .github/copilot-instructions.md | 103 ++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index a3f58bc..b73ae1a 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -5193,6 +5193,109 @@ trade.realizedPnL += actualRealizedPnL // NOT: result.realizedPnL from SDK * In real money trading, user relies on accurate notifications for manual intervention decisions * Cache lookups are critical path for all validation queue price checks (every 30 seconds) +68. **Smart Entry using webhook percentage as signal price (CRITICAL - Fixed Dec 3, 2025):** + - **Symptom:** $89 position sizes, 97% pullback calculations, impossible entry conditions preventing ALL Smart Entry trades + - **User Report:** "why is position size so tiny?" → $89 instead of expected $2,300 + - **Real Incident (Dec 3, 2025, 07:16-09:02 CET):** + * SOL-PERP LONG signal: Quality 92, market price $142.50 + * Expected: $2,300 position at 10x leverage + * Actual: $89 position blocked due to impossible Smart Entry condition + * Smart Entry log: "97.4% pullback required" (impossible to trigger) + - **Root Cause:** TradingView webhook `signal.price` field contained percentage value (70.80) instead of market price ($142.50) + ```typescript + // BUGGY CODE (OLD): + const signalPrice = signal.price // ❌ 70.80 (percentage from TradingView) + const currentPrice = 142.50 // Current SOL price + const pullbackPercent = ((currentPrice - signalPrice) / signalPrice) * 100 + // = ((142.50 - 70.80) / 70.80) * 100 = 101.2% pullback + // Smart Entry requires: actualPullback > pullbackPercent (impossible!) + ``` + - **Investigation Timeline:** + * 07:16 CET: Signal received, position opened with $89 size + * User noticed: "why so tiny?" + * Agent investigated: Position sizing code correct, leverage correct + * Discovery: Smart Entry calculating 97% pullback from wrong signal price + * Root cause: signal.price = 70.80 (TradingView percentage) not $142.50 (market price) + - **Fix:** Use Pyth current price instead of webhook signal price + ```typescript + // FIXED CODE (NEW): + // Get current price from Pyth (reliable market data) + const pythPrice = await pythClient.getPrice(symbol) + const signalPrice = pythPrice.price // ✅ Use actual market price, not webhook + + // Now pullback calculation makes sense: + // If price pulls back from $142.50 to $141.50 = 0.7% pullback (reasonable) + ``` + - **Files Modified:** + * `app/api/trading/execute/route.ts` - Smart Entry signal price source (lines ~680-700) + * Used Pyth price (already fetched for position sizing) instead of webhook price + - **Git Commit:** 7d0d38a "Fix Bug #1: Smart Entry uses wrong signal price (webhook percentage)" + - **Deployed:** Dec 3, 2025, 09:02:45 CET (container trading-bot-v4 restarted, timestamp verified: 09:02:45 > 08:16:27 ✅) + - **Verification Required:** + * Wait for next quality 90+ signal with Smart Entry conditions + * Expected: Signal price ~$140-145 (market price, not ~$80 percentage) + * Expected: Position size ~$2,300 (not $89) + * Expected: Pullback calculation <1% (not 97%) + - **Lessons Learned:** + 1. **Never trust webhook data for calculations** - Use authoritative price sources (Pyth, Drift) + 2. **TradingView alert payloads contain mixed data types** - Price fields may contain percentages, scores, or actual prices depending on alert configuration + 3. **Sanity check calculations** - 97% pullback requirement is impossible, should have caught this + 4. **Position sizing worked perfectly** - Bug was ONLY in Smart Entry, not position size logic + 5. **Investigate user complaints thoroughly** - "$89 position" led to discovering Smart Entry bug, not position sizing bug + 6. **Use already-fetched data** - Pyth price was already retrieved for position sizing, reuse for Smart Entry + - **Why This Matters:** + * Smart Entry is profit optimization feature (waits for better entry prices) + * Using wrong signal price made Smart Entry impossible to trigger + * All quality 90+ signals were opening with worse entries than possible + * Fix enables Smart Entry to work as designed (wait for 0.5-2% pullbacks) + * Position sizing bug was actually Smart Entry validation bug in disguise + +69. **Direction-specific leverage thresholds not explicit in code (Fixed Dec 3, 2025):** + - **Symptom:** Leverage assignment code checked `qualityResult.score >= 90` without explicit direction context + - **Risk:** High quality SHORT signal could potentially get LONG leverage configuration (or vice versa) + - **Code Pattern:** + ```typescript + // UNCLEAR CODE (OLD): + let leverage = 1 + if (qualityResult.score >= 90) { + leverage = 5 // Which direction? Not obvious + } else if (qualityResult.score >= 80) { + leverage = 4 + } + ``` + - **User Clarification (Dec 3, 2025):** Quality 90+ → 5x leverage for BOTH LONG and SHORT (intentional design) + - **Fix:** Made direction-specific thresholds explicit in code even though values are same + ```typescript + // EXPLICIT CODE (NEW): + let leverage = 1 + if (body.direction === 'LONG') { + if (qualityResult.score >= 90) leverage = 5 + else if (qualityResult.score >= 80) leverage = 4 + else if (qualityResult.score >= 70) leverage = 3 + else if (qualityResult.score >= 60) leverage = 2 + } else { // SHORT + if (qualityResult.score >= 90) leverage = 5 // Same as LONG but explicit + else if (qualityResult.score >= 80) leverage = 4 + else if (qualityResult.score >= 70) leverage = 3 + else if (qualityResult.score >= 60) leverage = 2 + } + ``` + - **Files Modified:** + * `app/api/trading/execute/route.ts` - Leverage determination logic + - **Git Commit:** 58f812f "Fix Bug #2: Make direction-specific leverage thresholds explicit" + - **Deployed:** Dec 3, 2025, 09:02:45 CET (same container restart as Bug #1) + - **Verification:** User confirmed quality 90+ → 5x for both directions is intentional design + - **Lessons Learned:** + 1. **Make direction context explicit** - Even if values are same, code clarity matters + 2. **Avoid ambiguous conditionals** - Future changes might need different thresholds per direction + 3. **Document intentional symmetry** - Same values for LONG/SHORT is design choice, not oversight + 4. **Code maintainability** - Explicit branches easier to modify when requirements change + - **Why This Matters:** + * Real money trading - leverage misconfiguration causes financial loss + * Future changes may need different thresholds for LONG vs SHORT + * Code clarity prevents future bugs when modifying leverage logic + * Explicit direction handling makes system behavior predictable + ## File Conventions - **API routes:** `app/api/[feature]/[action]/route.ts` (Next.js 15 App Router)