docs: update copilot-instructions for ATR trailing + dynamic runner% + rate limits

Updated .github/copilot-instructions.md to reflect recent system improvements:

**ATR-Based Trailing Stop:**
- Dynamic trailing calculation formula documented
- Configurable runner % (default 25%, adjustable via TAKE_PROFIT_1_SIZE_PERCENT)
- All UI displays now dynamically calculate runner% as 100 - TP1_SIZE
- Removed hardcoded '25%' references, replaced with dynamic language

**Rate Limit Monitoring:**
- NEW Section #4: Rate Limit Monitoring
- Exponential backoff mechanism (2s→4s→8s)
- Database logging (3 event types: hit/recovered/exhausted)
- Analytics endpoint for monitoring
- Links to RATE_LIMIT_MONITORING.md for SQL queries

**Section Renumbering:**
- Old Section #4 (Order Placement) → Section #5
- Old Section #5 (Database) → Section #6
- Maintains logical flow and consistency

**Updated References:**
- Exit Strategy: Dynamic runner% description
- Position Manager: ATR trailing formula + on-chain sync notes
- Common Pitfalls: Dynamic runner % configuration notes
- Roadmap: Phase 5 shows configurable runner with formula

All documentation now accurately reflects user's 70/30 TP1/Runner split
and recent infrastructure improvements (ATR trailing, rate limits).

Related: settings UI updated in previous commit (app/settings/page.tsx)
This commit is contained in:
mindesbunister
2025-11-11 20:40:05 +01:00
parent 03e91fc18d
commit 6a192bfb76
4 changed files with 353 additions and 22 deletions

View File

@@ -9,9 +9,10 @@
**Key Design Principle:** Dual-layer redundancy - every trade has both on-chain orders (Drift) AND software monitoring (Position Manager) as backup.
**Exit Strategy:** TP2-as-Runner system (CURRENT):
- TP1 at +0.4%: Close 75% (configurable via `TAKE_PROFIT_1_SIZE_PERCENT`)
- TP2 at +0.7%: **Activates trailing stop** on full 25% remaining (no position close)
- Runner: 25% remaining with ATR-based trailing stop (5x larger than old 5% system)
- TP1 at +0.4%: Close configurable % (default 75%, adjustable via `TAKE_PROFIT_1_SIZE_PERCENT`)
- TP2 at +0.7%: **Activates trailing stop** on full remaining % (no position close)
- Runner: Remaining % after TP1 with ATR-based trailing stop (default 25%, configurable)
- **Note:** All UI displays dynamically calculate runner% as `100 - TAKE_PROFIT_1_SIZE_PERCENT`
**Per-Symbol Configuration:** SOL and ETH have independent enable/disable toggles and position sizing:
- `SOLANA_ENABLED`, `SOLANA_POSITION_SIZE`, `SOLANA_LEVERAGE` (defaults: true, $210, 10x)
@@ -77,10 +78,11 @@ await positionManager.addTrade(activeTrade)
**Key behaviors:**
- Tracks `ActiveTrade` objects in a Map
- **TP2-as-Runner system**: TP1 (75%) → TP2 trigger (no close, activate trailing) → 25% runner with ATR-based trailing stop
- **TP2-as-Runner system**: TP1 (configurable %, default 75%) → TP2 trigger (no close, activate trailing) → Runner (remaining %) with ATR-based trailing stop
- Dynamic SL adjustments: Moves to breakeven after TP1, locks profit at +1.2%
- **On-chain order synchronization:** After TP1 hits, calls `cancelAllOrders()` then `placeExitOrders()` with updated SL price at breakeven
- Trailing stop: Activates when TP2 price hit, tracks `peakPrice` and trails by ATR-based %
- **On-chain order synchronization:** After TP1 hits, calls `cancelAllOrders()` then `placeExitOrders()` with updated SL price at breakeven (uses `retryWithBackoff()` for rate limit handling)
- **ATR-based trailing stop:** Calculates trail distance as `(atrAtEntry / currentPrice × 100) × trailingStopAtrMultiplier`, clamped between min/max %
- Trailing stop: Activates when TP2 price hit, tracks `peakPrice` and trails dynamically
- Closes positions via `closePosition()` market orders when targets hit
- Acts as backup if on-chain orders don't fill
- State persistence: Saves to database, restores on restart via `configSnapshot.positionManagerState`
@@ -131,7 +133,36 @@ const health = await driftService.getAccountHealth()
```
- Wallet handling: Supports both JSON array `[91,24,...]` and base58 string formats from Phantom wallet
### 4. Order Placement (`lib/drift/orders.ts`)
### 4. Rate Limit Monitoring (`lib/drift/orders.ts` + `app/api/analytics/rate-limits`)
**Purpose:** Track and analyze Solana RPC rate limiting (429 errors) to prevent silent failures
**Retry mechanism with exponential backoff:**
```typescript
await retryWithBackoff(async () => {
return await driftClient.cancelOrders(...)
}, maxRetries = 3, baseDelay = 2000)
```
**Database logging:** Three event types in SystemEvent table:
- `rate_limit_hit`: Each 429 error (logged with attempt #, delay, error snippet)
- `rate_limit_recovered`: Successful retry (logged with total time, retry count)
- `rate_limit_exhausted`: Failed after max retries (CRITICAL - order operation failed)
**Analytics endpoint:**
```bash
curl http://localhost:3001/api/analytics/rate-limits
```
Returns: Total hits/recoveries/failures, hourly patterns, recovery times, success rate
**Key behaviors:**
- Only RPC calls wrapped: `cancelAllOrders()`, `placeExitOrders()`, `closePosition()`
- Position Manager 2s loop does NOT make RPC calls (only price checks via Pyth WebSocket)
- Exponential backoff: 2s → 4s → 8s delays on retry
- Logs to both console and database for post-trade analysis
**Monitoring queries:** See `docs/RATE_LIMIT_MONITORING.md` for SQL queries
### 5. Order Placement (`lib/drift/orders.ts`)
**Critical functions:**
- `openPosition()` - Opens market position with transaction confirmation
- `closePosition()` - Closes position with transaction confirmation
@@ -205,7 +236,7 @@ Without this, order cancellations fail silently during TP1→breakeven order upd
- Soft SL: TRIGGER_LIMIT reduce-only
- Hard SL: TRIGGER_MARKET reduce-only
### 5. Database (`lib/database/trades.ts` + `prisma/schema.prisma`)
### 6. Database (`lib/database/trades.ts` + `prisma/schema.prisma`)
**Purpose:** PostgreSQL via Prisma ORM for trade history and analytics
**Models:** Trade, PriceUpdate, SystemEvent, DailyStats, BlockedSignal
@@ -551,9 +582,9 @@ ORDER BY MIN(adx) DESC;
8. **TP2-as-Runner configuration:**
- `takeProfit2SizePercent: 0` means "TP2 activates trailing stop, no position close"
- This creates 25% runner (vs old 5% system) for better profit capture
- This creates runner of remaining % after TP1 (default 25%, configurable via TAKE_PROFIT_1_SIZE_PERCENT)
- `TAKE_PROFIT_2_PERCENT=0.7` sets TP2 trigger price, `TAKE_PROFIT_2_SIZE_PERCENT` should be 0
- Settings UI correctly shows "TP2 activates trailing stop" instead of size percentage
- Settings UI correctly shows "TP2 activates trailing stop" with dynamic runner % calculation
9. **P&L calculation CRITICAL:** Use actual entry vs exit price calculation, not SDK values:
```typescript
@@ -750,10 +781,10 @@ See `POSITION_SCALING_ROADMAP.md` for planned position management optimizations:
- **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 (✅ COMPLETE):** TP2-as-runner system implemented - 25% runner with ATR-based trailing stop
- **Phase 5 (✅ COMPLETE):** TP2-as-runner system implemented - configurable runner (default 25%, adjustable via TAKE_PROFIT_1_SIZE_PERCENT) with ATR-based trailing stop
- **Phase 6:** ML-based exit prediction (future)
**Recent Implementation:** TP2-as-runner system provides 5x larger runner (25% vs 5%) for better profit capture on extended moves. When TP2 price is hit, trailing stop activates on full remaining position instead of closing partial amount.
**Recent Implementation:** TP2-as-runner system provides 5x larger runner (default 25% vs old 5%) for better profit capture on extended moves. When TP2 price is hit, trailing stop activates on full remaining position instead of closing partial amount. Runner size is configurable (100% - TP1 close %).
**Blocked Signals Tracking (Nov 11, 2025):** System now automatically saves all blocked signals to database for data-driven optimization. See `BLOCKED_SIGNALS_TRACKING.md` for SQL queries and analysis workflows.