From b2ff3026c66320dfe54340c22481beac05006342 Mon Sep 17 00:00:00 2001 From: mindesbunister Date: Fri, 9 Jan 2026 12:00:51 +0100 Subject: [PATCH] docs: Add Pyramiding/Position Stacking implementation plan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Create comprehensive PYRAMIDING_IMPLEMENTATION_PLAN.md with: - Data-driven justification (100% WR for signals ≤72 bars apart) - User-selected parameters (4h window, 7x→14x leverage) - ENV variables, database schema, execute endpoint logic - Position manager updates, Telegram notifications - 7-phase implementation checklist - 4 expected behavior examples - Add reference in copilot-instructions.md under Development Roadmap - Documents planned pyramiding system - Links to implementation plan for future agent --- .github/copilot-instructions.md | 72 +++++ docs/PYRAMIDING_IMPLEMENTATION_PLAN.md | 368 +++++++++++++++++++++++++ 2 files changed, 440 insertions(+) create mode 100644 docs/PYRAMIDING_IMPLEMENTATION_PLAN.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 85b5b0f..57e97c8 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -5947,6 +5947,78 @@ All technical improvements must align with current phase objectives (see top of - Comparison with executed trades at similar quality levels - Future automation of price tracking (would TP1/TP2/SL have hit?) +--- + +## šŸ”ŗ Pyramiding/Position Stacking System (Jan 6, 2026 - PLANNED) + +**Status:** šŸ“‹ PLANNED - Implementation plan ready, awaiting development + +**Purpose:** Scale into winning positions by adding to existing trades when confirmation signals arrive within a time window. Based on ML v11.2 backtesting analysis showing 100% win rate for signals ≤72 bars apart. + +**Implementation Plan:** See `docs/PYRAMIDING_IMPLEMENTATION_PLAN.md` for complete details + +**Key Parameters (User-Selected):** +- **Stacking Window:** 4 hours (240 minutes / 48 bars on 5-min chart) +- **Base Leverage:** 7x (first entry) +- **Stack Leverage:** 7x (additional entry) +- **Max Total Leverage:** 14x (7x + 7x = 2 pyramid levels) +- **Max Pyramid Levels:** 2 (base + 1 stack) + +**Data-Driven Justification:** +- Backtesting analysis of ML v11.2 pyramiding trades +- **≤72 bars (6 hours):** 100% win rate - signals close together confirm trend +- **>72 bars:** 67.6% win rate - too far apart, trend may have reversed +- User chose conservative 48-bar (4-hour) window for production + +**Environment Variables (New):** +```bash +ENABLE_PYRAMIDING=true +BASE_LEVERAGE=7 +STACK_LEVERAGE=7 +MAX_LEVERAGE_TOTAL=14 +MAX_PYRAMID_LEVELS=2 +STACKING_WINDOW_MINUTES=240 +``` + +**Database Schema Changes:** +```prisma +model Trade { + // ... existing fields + pyramidLevel Int? // 1 = base, 2 = first stack, etc. + parentTradeId String? // Links stacked trades to base + stackedAt DateTime? // When stack was added + totalLeverageAtEntry Float? // Running total leverage + isStackedPosition Boolean @default(false) +} +``` + +**Core Logic:** +1. First signal → Open position with 7x leverage (pyramidLevel: 1) +2. Second signal within 4 hours → Check if same direction + within window +3. If valid → Add 7x position (pyramidLevel: 2), total leverage now 14x +4. Position Manager tracks both as linked positions +5. Exit → Close ALL pyramid levels together (unified exit) + +**Safety Checks:** +- āœ… Same direction only (no hedging) +- āœ… Within stacking window (4 hours default) +- āœ… Max leverage cap (14x) +- āœ… Max pyramid levels (2) +- āœ… Sufficient free collateral for additional position + +**TradingView Strategy (Already Implemented):** +- File: `workflows/trading/moneyline_v11_2_strategy.pinescript` +- Has pyramiding=1 setting and barSpacingThreshold input +- Debug table shows bar spacing and stacking decisions + +**References:** +- Implementation plan: `docs/PYRAMIDING_IMPLEMENTATION_PLAN.md` +- TradingView strategy: `workflows/trading/moneyline_v11_2_strategy.pinescript` +- Backtesting data: `backtester/dynamic_threshold_backtest_20251223_152614.csv` +- Analysis document: `V11_COMPREHENSIVE_ANALYSIS_DEC17_2025.md` + +--- + ## Telegram Notifications (Nov 16, 2025 - Enhanced Nov 20, 2025) **Position Closure Notifications:** System sends direct Telegram messages for all position closures via `lib/notifications/telegram.ts` diff --git a/docs/PYRAMIDING_IMPLEMENTATION_PLAN.md b/docs/PYRAMIDING_IMPLEMENTATION_PLAN.md new file mode 100644 index 0000000..09feff7 --- /dev/null +++ b/docs/PYRAMIDING_IMPLEMENTATION_PLAN.md @@ -0,0 +1,368 @@ +# Pyramiding / Signal Stacking Implementation Plan + +**Created:** January 9, 2026 +**Status:** šŸ“‹ PLANNED - Ready for Implementation +**Priority:** HIGH - User-requested feature based on backtested data + +--- + +## šŸ“Š Background & Data-Driven Justification + +### Analysis Results (Jan 9, 2026) +From CSV analysis of ML v11.2 Long Only strategy on SOL/USDT 5-min chart: + +| Signal Spacing | Pairs | Win Rate | Avg Combined P&L | +|----------------|-------|----------|------------------| +| ≤72 bars (6h) | 9 | **100%** | +4.82% | +| >72 bars | 34 | 67.6% | +1.94% | + +**Key Finding:** Signals within 72 bars (6 hours) of each other have **100% win rate** - these represent trend confirmation and are ideal for stacking. + +### User-Selected Parameters +- **Stacking Window:** 4 hours (48 bars on 5-min chart) - conservative vs 6h optimal +- **Base Leverage:** 7x (down from previous 10x for safety) +- **Stacked Leverage:** 14x total (7x + 7x) +- **Max Pyramid Levels:** 2 (base + 1 stack) + +--- + +## šŸ—ļø Implementation Components + +### 1. Environment Variables (.env) + +```bash +# === PYRAMIDING / STACKING === +ENABLE_PYRAMIDING=true +BASE_LEVERAGE=7 +STACK_LEVERAGE=7 +MAX_LEVERAGE_TOTAL=14 +STACKING_WINDOW_MINUTES=240 # 4 hours = 48 bars on 5-min chart +MAX_PYRAMID_LEVELS=2 # Base + 1 additional stack + +# Per-symbol overrides (optional) +SOLANA_BASE_LEVERAGE=7 +SOLANA_MAX_LEVERAGE=14 +SOLANA_STACKING_WINDOW_MINUTES=240 +``` + +### 2. Configuration (config/trading.ts) + +Add to `TradingConfig` interface: +```typescript +interface TradingConfig { + // ... existing fields ... + + // Pyramiding settings + enablePyramiding: boolean; + baseLeverage: number; + stackLeverage: number; + maxLeverageTotal: number; + stackingWindowMinutes: number; + maxPyramidLevels: number; +} +``` + +Add to `DEFAULT_TRADING_CONFIG`: +```typescript +enablePyramiding: true, +baseLeverage: 7, +stackLeverage: 7, +maxLeverageTotal: 14, +stackingWindowMinutes: 240, // 4 hours +maxPyramidLevels: 2, +``` + +Add to `getConfigFromEnv()`: +```typescript +enablePyramiding: process.env.ENABLE_PYRAMIDING === 'true', +baseLeverage: parseInt(process.env.BASE_LEVERAGE || '7'), +stackLeverage: parseInt(process.env.STACK_LEVERAGE || '7'), +maxLeverageTotal: parseInt(process.env.MAX_LEVERAGE_TOTAL || '14'), +stackingWindowMinutes: parseInt(process.env.STACKING_WINDOW_MINUTES || '240'), +maxPyramidLevels: parseInt(process.env.MAX_PYRAMID_LEVELS || '2'), +``` + +### 3. Database Schema (prisma/schema.prisma) + +Add to Trade model: +```prisma +model Trade { + // ... existing fields ... + + // Pyramiding tracking + pyramidLevel Int? @default(1) // 1 = base, 2 = first stack, etc. + parentTradeId String? // Reference to base trade if stacked + stackedAt DateTime? // When stack was added + totalLeverageAtEntry Float? // Total leverage including stacks + isStackedPosition Boolean @default(false) // True if this is a stack entry +} +``` + +### 4. Execute Endpoint (app/api/trading/execute/route.ts) + +#### A. Add Stacking Logic Check + +Before opening a new position, check if we should stack: + +```typescript +// Check for existing open position in same direction +const existingOpenTrade = await prisma.trade.findFirst({ + where: { + symbol: driftSymbol, + direction: direction, + exitReason: null, // Still open + }, + orderBy: { createdAt: 'desc' } +}); + +// Determine if this is a stack opportunity +let isStackEntry = false; +let effectiveLeverage = config.baseLeverage; +let pyramidLevel = 1; + +if (existingOpenTrade && config.enablePyramiding) { + const minutesSinceEntry = (Date.now() - new Date(existingOpenTrade.createdAt).getTime()) / 60000; + const currentPyramidLevel = existingOpenTrade.pyramidLevel || 1; + + if (minutesSinceEntry <= config.stackingWindowMinutes && + currentPyramidLevel < config.maxPyramidLevels) { + // This is a valid stack opportunity + isStackEntry = true; + pyramidLevel = currentPyramidLevel + 1; + effectiveLeverage = config.stackLeverage; // Add another 7x + + console.log(`šŸ“ˆ PYRAMID STACK: Signal within ${minutesSinceEntry.toFixed(0)} minutes`) + console.log(` Level: ${pyramidLevel}/${config.maxPyramidLevels}`) + console.log(` Adding: ${effectiveLeverage}x leverage`) + console.log(` Total: ${currentPyramidLevel * config.baseLeverage + effectiveLeverage}x`) + } else if (minutesSinceEntry > config.stackingWindowMinutes) { + console.log(`ā° Stack window expired: ${minutesSinceEntry.toFixed(0)} min > ${config.stackingWindowMinutes} min`) + console.log(` Treating as independent signal (not stacking)`) + } else if (currentPyramidLevel >= config.maxPyramidLevels) { + console.log(`šŸ”’ Max pyramid level reached: ${currentPyramidLevel}/${config.maxPyramidLevels}`) + console.log(` Ignoring additional signal`) + return NextResponse.json({ + success: false, + error: 'Max pyramid level reached', + details: { currentLevel: currentPyramidLevel, maxLevel: config.maxPyramidLevels } + }); + } +} +``` + +#### B. Modify Position Opening + +When opening position, use the determined leverage: + +```typescript +// Use effective leverage (base or stack) +const positionParams = { + symbol: driftSymbol, + direction: direction, + leverage: effectiveLeverage, // 7x for both base and stack + // ... other params +}; +``` + +#### C. Update Database Record + +Store pyramiding info in trade record: + +```typescript +const tradeData = { + // ... existing fields ... + pyramidLevel: pyramidLevel, + parentTradeId: isStackEntry ? existingOpenTrade.id : null, + stackedAt: isStackEntry ? new Date() : null, + totalLeverageAtEntry: isStackEntry + ? (existingOpenTrade.totalLeverageAtEntry || config.baseLeverage) + effectiveLeverage + : effectiveLeverage, + isStackedPosition: isStackEntry, +}; +``` + +### 5. Position Manager (lib/trading/position-manager.ts) + +#### A. Track Stacked Positions Together + +Modify `ActiveTrade` interface: +```typescript +interface ActiveTrade { + // ... existing fields ... + pyramidLevel: number; + parentTradeId?: string; + isStackedPosition: boolean; + totalLeverage: number; +} +``` + +#### B. Unified Exit Logic + +When closing a position, close ALL pyramid levels: +```typescript +async closePosition(tradeId: string, reason: string) { + const trade = this.activeTrades.get(tradeId); + + // If this is a base position with stacks, close all + if (trade && !trade.isStackedPosition) { + const stackedTrades = Array.from(this.activeTrades.values()) + .filter(t => t.parentTradeId === tradeId); + + for (const stackedTrade of stackedTrades) { + console.log(`šŸ”— Closing stacked position: ${stackedTrade.id} (level ${stackedTrade.pyramidLevel})`); + await this.executeClose(stackedTrade, reason); + } + } + + await this.executeClose(trade, reason); +} +``` + +### 6. Telegram Notifications (lib/notifications/telegram.ts) + +Update position notifications to show pyramid info: + +```typescript +// For stacked entries +if (trade.isStackedPosition) { + message += `\nšŸ“ˆ PYRAMID STACK (Level ${trade.pyramidLevel}/${config.maxPyramidLevels})`; + message += `\nšŸ’Ŗ Total Leverage: ${trade.totalLeverageAtEntry}x`; + message += `\nā±ļø Stacked ${Math.round((Date.now() - new Date(trade.parentTrade.createdAt).getTime()) / 60000)} min after base`; +} +``` + +--- + +## šŸ”’ Risk Management Safeguards + +### Critical Safety Checks + +1. **Max Leverage Guard** + ```typescript + if (totalLeverage > config.maxLeverageTotal) { + console.error(`āŒ BLOCKED: Would exceed max leverage (${totalLeverage}x > ${config.maxLeverageTotal}x)`); + return; + } + ``` + +2. **Same Direction Only** + - Only stack in same direction as existing position + - Opposite signal should close existing position, not stack + +3. **Time Window Enforcement** + - Hard 4-hour (240 minute) window + - Signals outside window treated as independent trades + +4. **Max Levels Cap** + - Maximum 2 pyramid levels (base + 1 stack = 14x max) + - Additional signals beyond max are ignored with warning + +5. **Quality Score Requirement** + - Stacked entries should still pass quality score threshold + - Don't stack low-quality confirmations + +--- + +## šŸ“‹ Implementation Checklist + +### Phase 1: Configuration +- [ ] Add ENV variables to `.env` +- [ ] Update `TradingConfig` interface in `config/trading.ts` +- [ ] Add defaults to `DEFAULT_TRADING_CONFIG` +- [ ] Add ENV parsing to `getConfigFromEnv()` + +### Phase 2: Database +- [ ] Add new fields to Trade model in `prisma/schema.prisma` +- [ ] Run `npx prisma migrate dev --name add_pyramiding_fields` +- [ ] Run `npx prisma generate` + +### Phase 3: Execute Endpoint +- [ ] Add existing position check logic +- [ ] Add pyramid level calculation +- [ ] Add stacking window validation +- [ ] Modify position opening with effective leverage +- [ ] Update trade record with pyramid info +- [ ] Add logging for stack events + +### Phase 4: Position Manager +- [ ] Update ActiveTrade interface +- [ ] Add stack tracking to position Map +- [ ] Implement unified exit (close all levels together) +- [ ] Update MAE/MFE tracking for combined position + +### Phase 5: Notifications +- [ ] Update Telegram entry notification with stack info +- [ ] Update exit notification with combined P&L + +### Phase 6: Testing +- [ ] Test base entry (7x leverage) +- [ ] Test stack entry within window (14x total) +- [ ] Test signal outside window (independent trade) +- [ ] Test max pyramid level blocking +- [ ] Test unified exit closes all levels +- [ ] Test opposite direction closes stacked position + +### Phase 7: Documentation +- [ ] Update copilot-instructions.md with pyramiding section +- [ ] Add to Settings UI (optional) + +--- + +## šŸ“Š Expected Behavior Examples + +### Example 1: Successful Stack +``` +10:00 - BUY signal (quality 95) → Open LONG 7x leverage +12:30 - BUY signal (quality 92) → Stack! Within 4h window + → Add 7x leverage + → Total position: 14x leverage +14:00 - TP1 hit → Close entire stacked position + → P&L calculated on 14x total leverage +``` + +### Example 2: Outside Window +``` +10:00 - BUY signal → Open LONG 7x leverage +15:00 - BUY signal → 5 hours later, outside 4h window + → Treated as independent trade + → Close existing position, open new 7x position +``` + +### Example 3: Max Level Reached +``` +10:00 - BUY signal → Open LONG 7x (level 1) +11:00 - BUY signal → Stack 7x (level 2, total 14x) +12:00 - BUY signal → Max level reached! + → Log warning, ignore signal + → Keep existing 14x position +``` + +### Example 4: Opposite Signal +``` +10:00 - BUY signal → Open LONG 7x leverage +11:00 - SELL signal → Opposite direction! + → Close LONG position entirely + → Open new SHORT 7x position +``` + +--- + +## šŸ”— References + +- **Analysis Source:** `/home/icke/traderv4/docs/PYRAMIDING_IMPLEMENTATION_PLAN.md` +- **TradingView Strategy:** `/home/icke/traderv4/workflows/trading/moneyline_v11_2_strategy.pinescript` +- **CSV Analysis Data:** `ML_v11.2_Strat_MEXC_SOLUSDT.P_2026-01-09.csv` +- **Optimal Threshold Analysis:** 72 bars (6 hours) = 100% WR for stacked signals + +--- + +## āš ļø Important Notes + +1. **Conservative Window:** User chose 4 hours (48 bars) vs optimal 6 hours (72 bars) for safety +2. **Leverage Reduction:** Base leverage reduced from 10x to 7x to accommodate stacking safely +3. **Total Cap:** 14x maximum (7x + 7x) prevents over-leveraging +4. **Quality Gate:** Stack signals should still meet quality thresholds + +--- + +*This plan is ready for implementation. Reference this document when implementing pyramiding in the trading bot.*