Update copilot-instructions.md with latest system features

Major additions:
- Exit strategy details: 3-tier scaling (TP1 75%, TP2 80% of remaining, 5% runner with trailing stop)
- Signal quality system: 5 metrics scored 0-100, filters trades at 60+ threshold
- Runner implementation: Trailing stop activation after TP2, peakPrice tracking
- Database fields: signalQualityScore, MAE/MFE, configSnapshot for state persistence
- New API endpoints: /check-risk, /analytics/last-trade, /restart
- Updated workflows with quality score validation and runner management
- Common pitfalls: Quality score duplication, runner configuration confusion
- Development roadmap: Link to POSITION_SCALING_ROADMAP.md with 6 phases

Critical corrections:
- Position Manager singleton: getPositionManager() → getInitializedPositionManager()
- Updated monitoring loop details with external closure detection and state saving
This commit is contained in:
mindesbunister
2025-10-31 12:04:20 +01:00
parent 1e858cd25d
commit 27c6a06d31

View File

@@ -8,22 +8,32 @@
**Key Design Principle:** Dual-layer redundancy - every trade has both on-chain orders (Drift) AND software monitoring (Position Manager) as backup. **Key Design Principle:** Dual-layer redundancy - every trade has both on-chain orders (Drift) AND software monitoring (Position Manager) as backup.
**Exit Strategy:** Three-tier scaling system:
- TP1 at +1.5%: Close 75% (configurable via `TAKE_PROFIT_1_SIZE_PERCENT`)
- TP2 at +3.0%: Close 80% of remaining = 20% total (configurable via `TAKE_PROFIT_2_SIZE_PERCENT`)
- Runner: 5% remaining with 0.3% trailing stop (configurable via `TRAILING_STOP_PERCENT`)
**Signal Quality System:** Filters trades based on 5 metrics (ATR, ADX, RSI, volumeRatio, pricePosition) scored 0-100. Only trades scoring 60+ are executed. Scores stored in database for future optimization.
## Critical Components ## Critical Components
### 1. Position Manager (`lib/trading/position-manager.ts`) ### 1. Position Manager (`lib/trading/position-manager.ts`)
**Purpose:** Software-based monitoring loop that checks prices every 2 seconds and closes positions via market orders **Purpose:** Software-based monitoring loop that checks prices every 2 seconds and closes positions via market orders
**Singleton pattern:** Always use `getPositionManager()` - never instantiate directly **Singleton pattern:** Always use `getInitializedPositionManager()` - never instantiate directly
```typescript ```typescript
const positionManager = getPositionManager() const positionManager = await getInitializedPositionManager()
await positionManager.addTrade(activeTrade) await positionManager.addTrade(activeTrade)
``` ```
**Key behaviors:** **Key behaviors:**
- Tracks `ActiveTrade` objects in a Map - Tracks `ActiveTrade` objects in a Map
- Dynamic SL adjustments: Moves to breakeven at +0.5%, locks profit at +1.2% - Three-tier exits: TP1 (75%), TP2 (80% of remaining), Runner (with trailing stop)
- Dynamic SL adjustments: Moves to breakeven after TP1, locks profit at +1.2%
- Trailing stop: Activates after TP2, tracks `peakPrice` and trails by configured %
- Closes positions via `closePosition()` market orders when targets hit - Closes positions via `closePosition()` market orders when targets hit
- Acts as backup if on-chain orders don't fill - Acts as backup if on-chain orders don't fill
- State persistence: Saves to database, restores on restart via `configSnapshot.positionManagerState`
### 2. Drift Client (`lib/drift/client.ts`) ### 2. Drift Client (`lib/drift/client.ts`)
**Purpose:** Solana/Drift Protocol SDK wrapper for order execution **Purpose:** Solana/Drift Protocol SDK wrapper for order execution
@@ -59,10 +69,17 @@ const health = await driftService.getAccountHealth()
**Singleton pattern:** Use `getPrismaClient()` - never instantiate PrismaClient directly **Singleton pattern:** Use `getPrismaClient()` - never instantiate PrismaClient directly
**Key functions:** **Key functions:**
- `createTrade()` - Save trade after execution (includes dual stop TX signatures) - `createTrade()` - Save trade after execution (includes dual stop TX signatures + signalQualityScore)
- `updateTradeExit()` - Record exit with P&L - `updateTradeExit()` - Record exit with P&L
- `addPriceUpdate()` - Track price movements (called by Position Manager) - `addPriceUpdate()` - Track price movements (called by Position Manager)
- `getTradeStats()` - Win rate, profit factor, avg win/loss - `getTradeStats()` - Win rate, profit factor, avg win/loss
- `getLastTrade()` - Fetch most recent trade for analytics dashboard
**Important fields:**
- `signalQualityScore` (Int?) - 0-100 score for data-driven optimization
- `maxFavorableExcursion` / `maxAdverseExcursion` - Track best/worst P&L during trade lifetime
- `configSnapshot` (Json) - Stores Position Manager state for crash recovery
- `atr`, `adx`, `rsi`, `volumeRatio`, `pricePosition` - Context metrics from TradingView
## Configuration System ## Configuration System
@@ -92,36 +109,46 @@ const driftSymbol = normalizeTradingViewSymbol(body.symbol)
7. Add to Position Manager if applicable 7. Add to Position Manager if applicable
**Key endpoints:** **Key endpoints:**
- `/api/trading/execute` - Main entry point from n8n (production) - `/api/trading/execute` - Main entry point from n8n (production, requires auth)
- `/api/trading/check-risk` - Pre-execution validation (duplicate check, quality score, rate limits)
- `/api/trading/test` - Test trades from settings UI (no auth required) - `/api/trading/test` - Test trades from settings UI (no auth required)
- `/api/trading/close` - Manual position closing - `/api/trading/close` - Manual position closing
- `/api/trading/positions` - Query open positions - `/api/trading/positions` - Query open positions from Drift
- `/api/settings` - Get/update config (writes to .env file) - `/api/settings` - Get/update config (writes to .env file)
- `/api/analytics/last-trade` - Fetch most recent trade details for dashboard
- `/api/restart` - Create restart flag for watch-restart.sh script
## Critical Workflows ## Critical Workflows
### Execute Trade (Production) ### Execute Trade (Production)
``` ```
n8n webhook → /api/trading/execute TradingView alert → n8n Parse Signal Enhanced (extracts metrics)
↓ /api/trading/check-risk [validates quality score ≥60, checks duplicates]
↓ /api/trading/execute
↓ normalize symbol (SOLUSDT → SOL-PERP) ↓ normalize symbol (SOLUSDT → SOL-PERP)
↓ getMergedConfig() ↓ getMergedConfig()
↓ openPosition() [MARKET order] ↓ openPosition() [MARKET order]
↓ calculate dual stop prices if enabled ↓ calculate dual stop prices if enabled
↓ placeExitOrders() [on-chain TP/SL orders] ↓ placeExitOrders() [on-chain TP1/TP2/SL orders]
↓ createTrade() [save to database] ↓ calculateQualityScore() [compute 0-100 score from metrics]
↓ createTrade() [save to database with signalQualityScore]
↓ positionManager.addTrade() [start monitoring] ↓ positionManager.addTrade() [start monitoring]
``` ```
### Position Monitoring Loop ### Position Monitoring Loop
``` ```
Position Manager every 2s: Position Manager every 2s:
↓ Verify on-chain position still exists (detect external closures)
↓ getPythPriceMonitor().getLatestPrice() ↓ getPythPriceMonitor().getLatestPrice()
↓ Calculate current P&L ↓ Calculate current P&L and update peakPrice
↓ Check TP1 hit → closePosition(75%) ↓ Check emergency stop (-2%) → closePosition(100%)
↓ Check TP2 hit → closePosition(100%)
↓ Check SL hit → closePosition(100%) ↓ Check SL hit → closePosition(100%)
↓ Check dynamic adjustments (breakeven, profit lock) ↓ Check TP1 hit → closePosition(75%), move SL to breakeven
addPriceUpdate() [save to database] Check profit lock trigger (+1.2%) → move SL to +configured%
↓ Check TP2 hit → closePosition(80% of remaining), activate runner
↓ Check trailing stop (if runner active) → adjust SL dynamically based on peakPrice
↓ addPriceUpdate() [save to database every N checks]
↓ saveTradeState() [persist Position Manager state for crash recovery]
``` ```
### Settings Update ### Settings Update
@@ -234,6 +261,13 @@ docker exec trading-bot-postgres psql -U postgres -d trading_bot_v4 -c "\dt"
6. **Type errors with Prisma:** The Trade type from Prisma is only available AFTER `npx prisma generate` - use explicit types or `// @ts-ignore` carefully 6. **Type errors with Prisma:** The Trade type from Prisma is only available AFTER `npx prisma generate` - use explicit types or `// @ts-ignore` carefully
7. **Quality score duplication:** Signal quality calculation exists in BOTH `check-risk` and `execute` endpoints - keep logic synchronized
8. **Runner configuration confusion:**
- `TAKE_PROFIT_1_SIZE_PERCENT=75` means "close 75% at TP1" (not "keep 75%")
- `TAKE_PROFIT_2_SIZE_PERCENT=80` means "close 80% of REMAINING" (not of original)
- Actual runner size = (100 - TP1%) × (100 - TP2%) / 100 = 5% with defaults
## File Conventions ## File Conventions
- **API routes:** `app/api/[feature]/[action]/route.ts` (Next.js 15 App Router) - **API routes:** `app/api/[feature]/[action]/route.ts` (Next.js 15 App Router)
@@ -245,10 +279,24 @@ docker exec trading-bot-postgres psql -U postgres -d trading_bot_v4 -c "\dt"
## When Making Changes ## When Making Changes
1. **Adding new config:** Update DEFAULT_TRADING_CONFIG + getConfigFromEnv() + .env file 1. **Adding new config:** Update DEFAULT_TRADING_CONFIG + getConfigFromEnv() + .env file
2. **Adding database fields:** Update prisma/schema.prisma → migrate → regenerate client → rebuild Docker 2. **Adding database fields:** Update prisma/schema.prisma → `npx prisma migrate dev``npx prisma generate` → rebuild Docker
3. **Changing order logic:** Test with DRY_RUN=true first, use small position sizes ($10) 3. **Changing order logic:** Test with DRY_RUN=true first, use small position sizes ($10)
4. **API endpoint changes:** Update both endpoint + corresponding n8n workflow JSON 4. **API endpoint changes:** Update both endpoint + corresponding n8n workflow JSON (Check Risk and Execute Trade nodes)
5. **Docker changes:** Rebuild with `docker compose build trading-bot` then restart container 5. **Docker changes:** Rebuild with `docker compose build trading-bot` then restart container
6. **Modifying quality score logic:** Update BOTH `/api/trading/check-risk` and `/api/trading/execute` endpoints
7. **Exit strategy changes:** Modify Position Manager logic + update on-chain order placement in `placeExitOrders()`
## Development Roadmap
See `POSITION_SCALING_ROADMAP.md` for planned optimizations:
- **Phase 1 (CURRENT):** Collect data with quality scores (20-50 trades needed)
- **Phase 2:** ATR-based dynamic targets (adapt to volatility)
- **Phase 3:** Signal quality-based scaling (high quality = larger runners)
- **Phase 4:** Direction-based optimization (shorts vs longs have different performance)
- **Phase 5:** Optimize runner size (5% → 10-25%) and trailing stop (0.3% fixed → ATR-based)
- **Phase 6:** ML-based exit prediction (future)
**Data-driven approach:** Each phase requires validation through SQL analysis before implementation. No premature optimization.
## Integration Points ## Integration Points