/** * Test Pyth Price Monitor * * Tests real-time price monitoring with WebSocket and polling fallback */ import { getPythPriceMonitor } from './lib/pyth/price-monitor' interface PriceStats { symbol: string count: number prices: number[] minPrice: number maxPrice: number avgPrice: number lastUpdate: number } async function testPriceMonitor() { console.log('๐Ÿงช Testing Pyth Price Monitor...\n') const monitor = getPythPriceMonitor() const stats = new Map() const symbols = ['SOL-PERP', 'BTC-PERP', 'ETH-PERP'] // Initialize stats symbols.forEach(sym => { stats.set(sym, { symbol: sym, count: 0, prices: [], minPrice: Infinity, maxPrice: -Infinity, avgPrice: 0, lastUpdate: 0, }) }) console.log(`๐Ÿ“Š Monitoring: ${symbols.join(', ')}`) console.log('โฑ๏ธ Duration: 30 seconds') console.log('๐Ÿ“ก Source: Pyth Network (WebSocket + Polling)\n') // Start monitoring await monitor.start({ symbols, onPriceUpdate: (update) => { const stat = stats.get(update.symbol) if (!stat) return // Update statistics stat.count++ stat.prices.push(update.price) stat.minPrice = Math.min(stat.minPrice, update.price) stat.maxPrice = Math.max(stat.maxPrice, update.price) stat.avgPrice = stat.prices.reduce((a, b) => a + b, 0) / stat.prices.length stat.lastUpdate = Date.now() // Display update const changePercent = stat.prices.length > 1 ? ((update.price - stat.prices[0]) / stat.prices[0] * 100).toFixed(3) : '0.000' console.log( `๐Ÿ’ฐ ${update.symbol.padEnd(10)} ` + `$${update.price.toFixed(4).padStart(10)} ` + `(${changePercent > '0' ? '+' : ''}${changePercent}%) ` + `[${stat.count} updates]` ) }, }) console.log('โœ… Price monitor started!\n') // Run for 30 seconds const startTime = Date.now() await new Promise(resolve => setTimeout(resolve, 30000)) // Stop monitoring await monitor.stop() const duration = (Date.now() - startTime) / 1000 console.log('\n๐Ÿ“Š Test Results:\n') // Display statistics stats.forEach(stat => { const priceRange = stat.maxPrice - stat.minPrice const rangePercent = (priceRange / stat.minPrice * 100).toFixed(3) const updatesPerSec = (stat.count / duration).toFixed(2) const timeSinceUpdate = stat.lastUpdate ? (Date.now() - stat.lastUpdate) / 1000 : 0 console.log(`${stat.symbol}:`) console.log(` Updates: ${stat.count} (${updatesPerSec}/sec)`) console.log(` Avg Price: $${stat.avgPrice.toFixed(4)}`) console.log(` Min Price: $${stat.minPrice.toFixed(4)}`) console.log(` Max Price: $${stat.maxPrice.toFixed(4)}`) console.log(` Range: $${priceRange.toFixed(4)} (${rangePercent}%)`) console.log(` Last Update: ${timeSinceUpdate.toFixed(1)}s ago`) console.log() }) // Evaluate results console.log('โœ… Evaluation:\n') const allSymbolsUpdated = Array.from(stats.values()).every(s => s.count > 0) const avgUpdateRate = Array.from(stats.values()) .reduce((sum, s) => sum + s.count, 0) / stats.size / duration if (!allSymbolsUpdated) { console.log('โŒ FAIL: Not all symbols received updates') process.exit(1) } if (avgUpdateRate < 0.3) { console.log(`โš ๏ธ WARNING: Low update rate (${avgUpdateRate.toFixed(2)}/sec)`) console.log(' Expected: ~0.5-2 updates/sec per symbol') } else { console.log(`โœ… PASS: Good update rate (${avgUpdateRate.toFixed(2)}/sec)`) } const maxGap = Array.from(stats.values()) .map(s => s.lastUpdate ? (Date.now() - s.lastUpdate) / 1000 : Infinity) .reduce((max, gap) => Math.max(max, gap), 0) if (maxGap > 5) { console.log(`โš ๏ธ WARNING: Large gap since last update (${maxGap.toFixed(1)}s)`) } else { console.log(`โœ… PASS: Recent updates (${maxGap.toFixed(1)}s ago)`) } console.log('\n๐ŸŽ‰ Price monitor test complete!') console.log('\n๐Ÿ’ก Next steps:') console.log(' 1. If WebSocket is working: Updates should be ~0.5-2/sec') console.log(' 2. If polling fallback: Updates should be ~0.5/sec (every 2s)') console.log(' 3. Run test-position-manager.ts to test exit logic') } // Run test testPriceMonitor().catch(error => { console.error('โŒ Test failed:', error) process.exit(1) })