feat: Complete pyramiding/position stacking implementation (ALL 7 phases)

Phase 1: Configuration
- Added pyramiding config to trading.ts interface and defaults
- Added 6 ENV variables: ENABLE_PYRAMIDING, BASE_LEVERAGE, STACK_LEVERAGE,
  MAX_LEVERAGE_TOTAL, MAX_PYRAMID_LEVELS, STACKING_WINDOW_MINUTES

Phase 2: Database Schema
- Added 5 Trade fields: pyramidLevel, parentTradeId, stackedAt,
  totalLeverageAtEntry, isStackedPosition
- Added index on parentTradeId for pyramid group queries

Phase 3: Execute Endpoint
- Added findExistingPyramidBase() - finds active base trade within window
- Added canAddPyramidLevel() - validates pyramid conditions
- Stores pyramid metadata on new trades

Phase 4: Position Manager Core
- Added pyramidGroups Map for trade ID grouping
- Added addToPyramidGroup() - groups stacked trades by parent
- Added closeAllPyramidLevels() - unified exit for all levels
- Added getTotalPyramidLeverage() - calculates combined leverage
- All exit triggers now close entire pyramid group

Phase 5: Telegram Notifications
- Added sendPyramidStackNotification() - notifies on stack entry
- Added sendPyramidCloseNotification() - notifies on unified exit

Phase 6: Testing (25 tests, ALL PASSING)
- Pyramid Detection: 5 tests
- Pyramid Group Tracking: 4 tests
- Unified Exit: 4 tests
- Leverage Calculation: 4 tests
- Notification Context: 2 tests
- Edge Cases: 6 tests

Phase 7: Documentation
- Updated .github/copilot-instructions.md with full implementation details
- Updated docs/PYRAMIDING_IMPLEMENTATION_PLAN.md status to COMPLETE

Parameters: 4h window, 7x base/stack leverage, 14x max total, 2 max levels
Data-driven: 100% win rate for signals ≤72 bars apart in backtesting
This commit is contained in:
mindesbunister
2026-01-09 13:53:05 +01:00
parent b2ff3026c6
commit 96d1667ae6
17 changed files with 2384 additions and 56 deletions

View File

@@ -5949,13 +5949,20 @@ All technical improvements must align with current phase objectives (see top of
---
## 🔺 Pyramiding/Position Stacking System (Jan 6, 2026 - PLANNED)
## 🔺 Pyramiding/Position Stacking System (Jan 9, 2026 - ✅ IMPLEMENTED)
**Status:** 📋 PLANNED - Implementation plan ready, awaiting development
**Status:** ✅ FULLY IMPLEMENTED AND TESTED - Ready for production deployment
**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
**Implementation Summary:** 7-phase implementation completed Jan 9, 2026
- Phase 1: Configuration ✅
- Phase 2: Database Schema ✅
- Phase 3: Execute Endpoint ✅
- Phase 4: Position Manager Core ✅
- Phase 5: Telegram Notifications ✅
- Phase 6: Testing ✅ (25 tests, ALL PASSING)
- Phase 7: Documentation ✅
**Key Parameters (User-Selected):**
- **Stacking Window:** 4 hours (240 minutes / 48 bars on 5-min chart)
@@ -5970,8 +5977,9 @@ All technical improvements must align with current phase objectives (see top of
- **>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):**
**Environment Variables:**
```bash
# In .env file
ENABLE_PYRAMIDING=true
BASE_LEVERAGE=7
STACK_LEVERAGE=7
@@ -5980,36 +5988,86 @@ MAX_PYRAMID_LEVELS=2
STACKING_WINDOW_MINUTES=240
```
**Database Schema Changes:**
**Database Schema (prisma/schema.prisma):**
```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)
pyramidLevel Int? @default(1) // 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) // True if this is a stack entry
@@index([parentTradeId]) // For pyramid group queries
}
```
**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)
**Core Logic Flow:**
1. **First signal** → Open position with 7x leverage (`pyramidLevel: 1`)
2. **Second signal within 4 hours** → Check same direction + within window + under max levels
3. **If valid** → Add 7x position (`pyramidLevel: 2`, `parentTradeId` = base trade ID)
4. **Position Manager** tracks pyramid group via `pyramidGroups` Map
5. **Exit** → Close ALL pyramid levels together via `closeAllPyramidLevels()` (unified exit)
**Safety Checks:**
**Execute Endpoint Integration (`app/api/trading/execute/route.ts`):**
- `findExistingPyramidBase()`: Finds active base trade for same symbol/direction within window
- `canAddPyramidLevel()`: Validates pyramid conditions (levels, leverage, window)
- New trades set `parentTradeId`, `pyramidLevel`, `isStackedPosition`, `stackedAt`
- Logs: `🔺 PYRAMID STACK: Adding level X to base trade {id}`
**Position Manager Integration (`lib/trading/position-manager.ts`):**
- `pyramidGroups: Map<string, Set<string>>` - Tracks trade IDs by parent ID
- `addToPyramidGroup(tradeId, parentTradeId)`: Groups stacked trades
- `closeAllPyramidLevels(parentTradeId)`: Unified exit for all levels
- `getTotalPyramidLeverage(parentTradeId)`: Calculates combined leverage
- `getPyramidGroupTrades(parentTradeId)`: Returns all trades in group
- All exit reasons trigger unified close (TP1, TP2, SL, trailing, emergency)
**Telegram Notifications (`lib/notifications/telegram.ts`):**
- `sendPyramidStackNotification()`: Notifies on new stack entry
- `sendPyramidCloseNotification()`: Notifies on unified exit with combined P&L
- Shows: pyramid level, combined leverage, total P&L across all levels
**Safety Checks (All Implemented):**
- ✅ 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
- ✅ Sufficient free collateral validation
- ✅ Base trade must be open and active
- ✅ Unified exit prevents orphaned positions
**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
**Test Coverage (`tests/integration/position-manager/pyramiding.test.ts`):**
- **25 tests** across 6 test suites, ALL PASSING
- Pyramid Detection: 5 tests
- Pyramid Group Tracking: 4 tests
- Unified Exit: 4 tests
- Leverage Calculation: 4 tests
- Notification Context: 2 tests
- Edge Cases: 6 tests (window boundaries, leverage limits, mixed P&L)
**Files Modified:**
- `config/trading.ts` - Pyramiding configuration interface and defaults
- `.env` - 6 new environment variables
- `prisma/schema.prisma` - 5 new Trade fields + index
- `lib/database/trades.ts` - CreateTradeParams with pyramiding fields
- `app/api/trading/execute/route.ts` - Pyramid detection and creation logic
- `lib/trading/position-manager.ts` - Group tracking and unified exit
- `lib/notifications/telegram.ts` - Pyramid-specific notifications
- `tests/integration/position-manager/pyramiding.test.ts` - Comprehensive test suite
**Deployment Requirements:**
```bash
# 1. Run database migration
npx prisma migrate dev --name add_pyramiding_fields
# 2. Rebuild Docker container
docker compose build trading-bot
docker compose up -d --force-recreate trading-bot
# 3. Verify deployment
docker logs trading-bot-v4 | grep -i "pyramid"
```
**References:**
- Implementation plan: `docs/PYRAMIDING_IMPLEMENTATION_PLAN.md`