- New /api/trading/sync-positions endpoint (no auth) - Fetches actual Drift positions and compares with Position Manager - Removes stale tracking, adds missing positions with calculated TP/SL - Settings UI: Orange 'Sync Positions' button added - CLI script: scripts/sync-positions.sh for terminal access - Full documentation in docs/guides/POSITION_SYNC_GUIDE.md - Quick reference: POSITION_SYNC_QUICK_REF.md - Updated AI instructions with pitfall #23 Problem solved: Manual Telegram trades with partial fills can cause Position Manager to lose tracking, leaving positions without software- based stop loss protection. This feature restores dual-layer protection. Note: Docker build not picking up route yet (cache issue), needs investigation
129 lines
3.8 KiB
Markdown
129 lines
3.8 KiB
Markdown
# Position Re-Sync Feature
|
|
|
|
## Problem Solved
|
|
|
|
When manual Telegram trades are partially closed by on-chain orders, the Position Manager can lose tracking of the remaining position. This leaves the position without software-based stop loss protection, creating risk.
|
|
|
|
## Solution
|
|
|
|
Created `/api/trading/sync-positions` endpoint that:
|
|
1. Fetches all actual open positions from Drift
|
|
2. Compares against Position Manager's tracked trades
|
|
3. Removes tracking for positions that don't exist on Drift (cleanup)
|
|
4. Adds tracking for positions that exist on Drift but aren't being monitored
|
|
|
|
## Usage
|
|
|
|
### Via UI (Settings Page)
|
|
1. Go to http://localhost:3001/settings
|
|
2. Click "🔄 Sync Positions" button (orange button next to Restart Bot)
|
|
3. View sync results in success message
|
|
|
|
### Via Terminal
|
|
```bash
|
|
cd /home/icke/traderv4
|
|
bash scripts/sync-positions.sh
|
|
```
|
|
|
|
### Via API
|
|
```bash
|
|
curl -X POST http://localhost:3001/api/trading/sync-positions \
|
|
-H "Authorization: Bearer $API_SECRET_KEY" \
|
|
| jq '.'
|
|
```
|
|
|
|
## Response Format
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Position sync complete",
|
|
"results": {
|
|
"drift_positions": 1,
|
|
"tracked_positions": 0,
|
|
"added": ["SOL-PERP"],
|
|
"removed": [],
|
|
"unchanged": [],
|
|
"errors": []
|
|
},
|
|
"details": {
|
|
"drift_positions": [
|
|
{
|
|
"symbol": "SOL-PERP",
|
|
"direction": "short",
|
|
"size": 4.93,
|
|
"entry": 167.38,
|
|
"pnl": 8.15
|
|
}
|
|
],
|
|
"now_tracking": [
|
|
{
|
|
"symbol": "SOL-PERP",
|
|
"direction": "short",
|
|
"entry": 167.38
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
## When to Use
|
|
|
|
- **After Telegram manual trades** - If position remains open but isn't being tracked
|
|
- **After bot restarts** - If Position Manager lost in-memory state
|
|
- **After partial fills** - When on-chain orders close position in chunks
|
|
- **Rate limiting issues** - If 429 errors prevented proper monitoring
|
|
- **Manual interventions** - If you modified position directly on Drift
|
|
|
|
## How It Works
|
|
|
|
1. Queries Drift for all open positions (SOL-PERP, BTC-PERP, ETH-PERP)
|
|
2. Gets current oracle price for each position
|
|
3. Calculates TP/SL targets based on current config
|
|
4. Creates ActiveTrade objects with synthetic IDs (since we don't know original TX)
|
|
5. Adds to Position Manager for monitoring
|
|
6. Position Manager then protects position with emergency stop, trailing stop, etc.
|
|
|
|
## Limitations
|
|
|
|
- **Entry time unknown** - Assumes position opened 1 hour ago (doesn't affect TP/SL logic)
|
|
- **Signal quality metrics missing** - No ATR/ADX data (only matters for scaling)
|
|
- **Original config unknown** - Uses current config, not config when trade opened
|
|
- **Synthetic position ID** - Uses `manual-{timestamp}` instead of actual TX signature
|
|
|
|
## Safety Notes
|
|
|
|
- No auth required (same as test endpoint) - internal use only
|
|
- Won't open new positions - only adds tracking for existing ones
|
|
- Cleans up tracking for positions that were closed externally
|
|
- Marks cleaned positions as "sync_cleanup" in database
|
|
|
|
## Files Changed
|
|
|
|
1. `app/api/trading/sync-positions/route.ts` - Main endpoint
|
|
2. `app/settings/page.tsx` - Added UI button and sync function
|
|
3. `scripts/sync-positions.sh` - CLI helper script
|
|
|
|
## Example Scenario (Today's Issue)
|
|
|
|
**Before Sync:**
|
|
- Drift: 4.93 SOL SHORT position open at $167.38
|
|
- Position Manager: 0 active trades
|
|
- Database: Position marked as "closed"
|
|
- Result: NO STOP LOSS PROTECTION ⚠️
|
|
|
|
**After Sync:**
|
|
- Position Manager detects 4.93 SOL SHORT
|
|
- Calculates SL at $168.89 (-0.9%)
|
|
- Calculates TP1 at $166.71 (+0.4%)
|
|
- Starts monitoring every 2 seconds
|
|
- Result: DUAL-LAYER PROTECTION RESTORED ✅
|
|
|
|
## Future Improvements
|
|
|
|
- Auto-sync on startup (currently manual only)
|
|
- Periodic auto-sync every N minutes
|
|
- Alert if positions drift out of sync
|
|
- Restore original signal quality metrics from database
|
|
- Better handling of partial fill history
|