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)
This commit is contained in:
mindesbunister
2025-12-03 10:27:07 +01:00
parent 7d0d38a8b0
commit 0f88d88dd3

View File

@@ -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)