diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 26e259a..04f2144 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -90,6 +90,21 @@ - **Expected impact:** ~3.1% more trades (quality 90-94 longs), +$44.77 potential profit, prevent -$553.76 losses - **See:** `docs/DIRECTION_SPECIFIC_QUALITY_THRESHOLDS.md` for complete analysis and SQL queries +**Adaptive Leverage System (Nov 24, 2025 - RISK-ADJUSTED POSITION SIZING):** +- **Purpose:** Automatically adjust leverage based on signal quality score - high confidence gets full leverage, borderline signals get reduced risk exposure +- **Quality-Based Leverage Tiers:** + - **Quality 95-100:** 15x leverage ($540 × 15x = $8,100 notional position) + - **Quality 90-94:** 10x leverage ($540 × 10x = $5,400 notional position) + - **Quality <90:** Blocked by direction-specific thresholds +- **Risk Impact:** Quality 90-94 signals save $2,700 exposure (33% risk reduction) vs fixed 15x +- **Data-Driven Justification:** v8 indicator quality 95+ = 100% WR (4/4 wins), quality 90-94 more volatile +- **Configuration:** `USE_ADAPTIVE_LEVERAGE=true`, `HIGH_QUALITY_LEVERAGE=15`, `LOW_QUALITY_LEVERAGE=10`, `QUALITY_LEVERAGE_THRESHOLD=95` in .env +- **Implementation:** Quality score calculated EARLY in execute endpoint (before position sizing), passed to `getActualPositionSizeForSymbol(qualityScore)`, leverage determined via `getLeverageForQualityScore()` helper +- **Log Message:** `📊 Adaptive leverage: Quality X → Yx leverage (threshold: 95)` +- **Trade-off:** ~$21 less profit on borderline wins, but ~$21 less loss on borderline stops = better risk-adjusted returns +- **Future Enhancements:** Multi-tier (20x for 97+, 5x for 85-89), per-direction multipliers, streak-based adjustments +- **See:** `ADAPTIVE_LEVERAGE_SYSTEM.md` for complete implementation details, code examples, monitoring procedures + **Timeframe-Aware Scoring:** Signal quality thresholds adjust based on timeframe (5min vs daily): - 5min: ADX 12+ trending (vs 18+ for daily), ATR 0.2-0.7% healthy (vs 0.4%+ for daily) - Anti-chop filter: -20 points for extreme sideways (ADX <10, ATR <0.25%, Vol <0.9x) @@ -1118,6 +1133,20 @@ if (!enabled) { const driftSymbol = normalizeTradingViewSymbol(body.symbol) ``` +**Adaptive Leverage Configuration:** +- **Helper function:** `getLeverageForQualityScore(qualityScore, config)` returns leverage tier based on quality +- **Quality threshold:** Configured via `QUALITY_LEVERAGE_THRESHOLD` (default: 95) +- **Leverage tiers:** HIGH_QUALITY_LEVERAGE (default: 15x), LOW_QUALITY_LEVERAGE (default: 10x) +- **Integration:** Pass `qualityScore` parameter to `getActualPositionSizeForSymbol(symbol, config, qualityScore?)` +- **Flow:** Quality score → getLeverageForQualityScore() → returns 15x or 10x → applied to position sizing +- **Logging:** System logs adaptive leverage decisions for monitoring and validation +```typescript +// Example usage in execute endpoint +const qualityResult = scoreSignalQuality({ atr, adx, rsi, volumeRatio, pricePosition, timeframe }) +const { size, leverage } = getActualPositionSizeForSymbol(driftSymbol, config, qualityResult.score) +// leverage is now 15x for quality ≥95, or 10x for quality 90-94 +``` + ## API Endpoints Architecture **Authentication:** All `/api/trading/*` endpoints (except `/test`) require `Authorization: Bearer API_SECRET_KEY` @@ -1155,15 +1184,23 @@ TradingView alert → n8n Parse Signal Enhanced (extracts metrics + timeframe) ↓ /api/trading/execute ↓ normalize symbol (SOLUSDT → SOL-PERP) ↓ getMergedConfig() - ↓ getPositionSizeForSymbol() [check if symbol enabled + get sizing] - ↓ openPosition() [MARKET order] + ↓ scoreSignalQuality({ ..., timeframe }) [CRITICAL: calculate EARLY, before position sizing] + ↓ getPositionSizeForSymbol(qualityScore) [adaptive leverage based on quality score] + ↓ openPosition() [MARKET order with adaptive leverage] ↓ calculate dual stop prices if enabled ↓ placeExitOrders() [on-chain TP1/TP2/SL orders] - ↓ scoreSignalQuality({ ..., timeframe }) [compute 0-100 score with timeframe-aware thresholds] ↓ createTrade() [CRITICAL: save to database FIRST - see Common Pitfall #27] ↓ positionManager.addTrade() [ONLY after DB save succeeds - prevents unprotected positions] ``` +**CRITICAL EXECUTION ORDER (Nov 24, 2025 - Adaptive Leverage):** +The order of quality scoring → position sizing is NOT arbitrary - it's a requirement: +- Quality score MUST be calculated BEFORE position sizing +- Adaptive leverage depends on quality score value +- Old flow: Open position → Calculate quality → Save to DB (quality used for records only) +- New flow: Calculate quality → Determine leverage → Open position with adaptive size +- **Never calculate quality after position opening** - leverage must be determined first + **CRITICAL EXECUTION ORDER (Nov 13, 2025 Fix):** The order of database save → Position Manager add is NOT arbitrary - it's a safety requirement: - If database save fails, API returns HTTP 500 with critical warning @@ -3846,13 +3883,20 @@ if (!enabled) { - Never assume SDK data format - log raw values to verify - SQL query with manual calculation to compare results - Test boundary cases: 0%, 100%, min/max values -11. **DEPLOYMENT VERIFICATION (MANDATORY):** Before declaring ANY fix working: +13. **Adaptive leverage changes:** When modifying quality-based leverage tiers + - Quality score MUST be calculated BEFORE position sizing (execute endpoint line ~172) + - Update `getLeverageForQualityScore()` helper in config/trading.ts + - Test with known quality scores to verify tier selection (95+ = 15x, 90-94 = 10x) + - Log shows: `📊 Adaptive leverage: Quality X → Yx leverage (threshold: 95)` + - Update ENV variables: USE_ADAPTIVE_LEVERAGE, HIGH_QUALITY_LEVERAGE, LOW_QUALITY_LEVERAGE, QUALITY_LEVERAGE_THRESHOLD + - Monitor first 10-20 trades to verify correct leverage applied +14. **DEPLOYMENT VERIFICATION (MANDATORY):** Before declaring ANY fix working: - Check container start time vs commit timestamp - If container older than commit: CODE NOT DEPLOYED - Restart container and verify new code is running - Never say "fixed" or "protected" without deployment confirmation - This is a REAL MONEY system - unverified fixes cause losses -12. **GIT COMMIT AND PUSH (MANDATORY):** After completing ANY feature, fix, or significant change: +15. **GIT COMMIT AND PUSH (MANDATORY):** After completing ANY feature, fix, or significant change: - ALWAYS commit changes with descriptive message - ALWAYS push to remote repository - User should NOT have to ask for this - it's part of completion @@ -3884,7 +3928,7 @@ if (!enabled) { * `critical: Fix withdrawal statistics to use actual Drift deposits` (8d53c4b, Nov 19, 2025) - Query cumulativeDeposits from Drift ($1,440.61 vs hardcoded $546) - Created /api/drift/account-summary endpoint -13. **DOCKER MAINTENANCE (AFTER BUILDS):** Clean up accumulated cache to prevent disk full: +16. **DOCKER MAINTENANCE (AFTER BUILDS):** Clean up accumulated cache to prevent disk full: ```bash # Remove dangling images (old builds) docker image prune -f @@ -3903,14 +3947,14 @@ if (!enabled) { - **Safe to delete:** `` tagged images, build cache (recreated on next build), dangling volumes - **Keep:** Named volumes (`trading-bot-postgres`), active containers, tagged images in use - **Why critical:** Docker builds create 1.3+ GB per build, cache accumulates to 40-50 GB without cleanup -14. **NEXTCLOUD DECK SYNC (MANDATORY):** After completing phases or making significant roadmap progress: +17. **NEXTCLOUD DECK SYNC (MANDATORY):** After completing phases or making significant roadmap progress: - Update roadmap markdown files with new status (🔄 IN PROGRESS, ✅ COMPLETE, 🔜 NEXT) - Run sync to update Deck cards: `python3 scripts/sync-roadmap-to-deck.py --init` - Move cards between stacks in Nextcloud Deck UI to reflect progress visually - Backlog (📥) → Planning (📋) → In Progress (🚀) → Complete (✅) - Keep Deck in sync with actual work - it's the visual roadmap tracker - Documentation: `docs/NEXTCLOUD_DECK_SYNC.md` -15. **UPDATE COPILOT-INSTRUCTIONS.MD (MANDATORY):** After implementing ANY significant feature or system change: +18. **UPDATE COPILOT-INSTRUCTIONS.MD (MANDATORY):** After implementing ANY significant feature or system change: - Document new database fields and their purpose - Add filtering requirements (e.g., manual vs TradingView trades) - Update "Important fields" sections with new schema changes