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:
80
.github/copilot-instructions.md
vendored
80
.github/copilot-instructions.md
vendored
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user