/** * Test Full Trading Flow * * End-to-end test: Execute trade โ†’ Monitor โ†’ Auto-exit * * WARNING: This executes a REAL trade on Drift! * Make sure you have a small position size configured. */ import 'dotenv/config' const API_URL = process.env.API_URL || 'http://localhost:3000' const API_KEY = process.env.API_KEY || '' interface ExecuteResponse { success: boolean message: string trade?: { id: string symbol: string direction: string entryPrice: number positionSize: number leverage: number } position?: any } interface PositionsResponse { success: boolean monitoring: { isActive: boolean tradeCount: number symbols: string[] } positions: Array<{ id: string symbol: string direction: string entryPrice: number currentPrice: number unrealizedPnL: number profitPercent: number accountPnL: number tp1Hit: boolean slMovedToBreakeven: boolean }> } async function testFullFlow() { console.log('๐Ÿงช Testing Full Trading Flow (END-TO-END)\n') console.log('โš ๏ธ WARNING: This will execute a REAL trade on Drift!') console.log(' Make sure position size is small ($10-50)\n') if (!API_KEY) { console.error('โŒ Error: API_KEY not set in .env') console.log(' Add: API_KEY=your_secret_key_here') process.exit(1) } // Wait for user confirmation console.log('Press Ctrl+C to cancel, or wait 5 seconds to continue...') await new Promise(resolve => setTimeout(resolve, 5000)) console.log() // Step 1: Execute trade console.log('๐Ÿ“ Step 1: Executing trade...') const executePayload = { symbol: 'SOLUSDT', direction: 'long', timeframe: '5', } console.log(' Payload:', JSON.stringify(executePayload, null, 2)) const executeResponse = await fetch(`${API_URL}/api/trading/execute`, { method: 'POST', headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify(executePayload), }) if (!executeResponse.ok) { const error = await executeResponse.text() console.error('โŒ Execute failed:', error) process.exit(1) } const executeData: ExecuteResponse = await executeResponse.json() if (!executeData.success || !executeData.trade) { console.error('โŒ Execute failed:', executeData.message) process.exit(1) } console.log('โœ… Trade executed!') console.log(' ID:', executeData.trade.id) console.log(' Symbol:', executeData.trade.symbol) console.log(' Direction:', executeData.trade.direction.toUpperCase()) console.log(' Entry Price: $', executeData.trade.entryPrice.toFixed(4)) console.log(' Position Size: $', executeData.trade.positionSize.toFixed(2)) console.log(' Leverage:', executeData.trade.leverage + 'x') console.log() const tradeId = executeData.trade.id // Step 2: Monitor position console.log('๐Ÿ“ Step 2: Monitoring position...') console.log(' Duration: 120 seconds (2 minutes)') console.log(' Updates: Every 10 seconds') console.log(' Waiting for automatic exit...\n') const startTime = Date.now() let lastStatus: PositionsResponse | null = null for (let i = 0; i < 12; i++) { // 12 x 10s = 120s await new Promise(resolve => setTimeout(resolve, 10000)) const elapsed = (Date.now() - startTime) / 1000 console.log(`โฑ๏ธ ${elapsed.toFixed(0)}s elapsed...`) // Fetch positions const positionsResponse = await fetch(`${API_URL}/api/trading/positions`, { headers: { 'Authorization': `Bearer ${API_KEY}`, }, }) if (!positionsResponse.ok) { console.error(' โš ๏ธ Failed to fetch positions') continue } const positionsData: PositionsResponse = await positionsResponse.json() lastStatus = positionsData // Find our trade const ourTrade = positionsData.positions.find(p => p.id === tradeId) if (!ourTrade) { console.log(' โœ… TRADE CLOSED AUTOMATICALLY!') console.log(' Position no longer in active list') break } // Display status console.log(` Current Price: $${ourTrade.currentPrice.toFixed(4)}`) console.log(` Unrealized P&L: $${ourTrade.unrealizedPnL.toFixed(2)} (${ourTrade.accountPnL.toFixed(2)}% account)`) console.log(` TP1 Hit: ${ourTrade.tp1Hit ? 'YES โœ…' : 'No'}`) console.log(` SL Moved: ${ourTrade.slMovedToBreakeven ? 'YES โœ…' : 'No'}`) console.log() } // Step 3: Final check console.log('๐Ÿ“ Step 3: Final check...') const finalResponse = await fetch(`${API_URL}/api/trading/positions`, { headers: { 'Authorization': `Bearer ${API_KEY}`, }, }) if (finalResponse.ok) { const finalData: PositionsResponse = await finalResponse.json() const stillActive = finalData.positions.find(p => p.id === tradeId) if (stillActive) { console.log('โš ๏ธ Trade still active after 2 minutes') console.log(' This is normal if price hasn\'t hit targets yet') console.log(' Position will auto-close when TP/SL is hit') console.log() console.log(' Current status:') console.log(' Price:', stillActive.currentPrice) console.log(' P&L:', stillActive.unrealizedPnL.toFixed(2)) console.log(' TP1 Hit:', stillActive.tp1Hit) } else { console.log('โœ… Trade successfully closed automatically!') console.log(' Check your Drift account for final P&L') } } console.log() console.log('๐ŸŽ‰ End-to-end test complete!') console.log() console.log('๐Ÿ“Š What happened:') console.log(' 1. Trade was executed via API') console.log(' 2. Position manager started monitoring') console.log(' 3. Pyth price monitor updated every 2s') console.log(' 4. Exit conditions checked automatically') console.log(' 5. Trade closed when TP/SL was hit') console.log() console.log('๐Ÿ’ก Next steps:') console.log(' 1. Trigger more trades from TradingView') console.log(' 2. Monitor the logs for auto-exits') console.log(' 3. Verify P&L on Drift UI') console.log(' 4. Adjust parameters if needed') } // Run test testFullFlow().catch(error => { console.error('โŒ Test failed:', error) process.exit(1) })