🧹 Integrate orphaned order cleanup into position monitoring

FEATURES:
- Position monitor now automatically detects orphaned orders when no positions
- Triggers cleanup only when hasPosition: false to eliminate redundant polling
- Provides detailed cleanup results in monitoring response
- Leverages existing frequent position checks vs separate timers

- Modified /app/api/automation/position-monitor/route.js to check for orphaned orders
- Calls existing /api/drift/cleanup-orders endpoint when no positions detected
- Returns cleanup status, success/failure, and summary in monitoring response
- Handles cleanup errors gracefully with detailed error reporting

- Eliminates need for separate 60-second cleanup polling
- Uses existing position monitoring infrastructure
- Only runs cleanup when positions close (triggered by hasPosition: false)
- Automatic handling of orphaned orders after SL/TP execution

- Added test-orphaned-cleanup-integration.js for verification
- Tests both position monitor integration and direct cleanup API
- Provides detailed feedback on cleanup operations

This completes the automation enhancement requested - no more manual cleanup needed!
This commit is contained in:
mindesbunister
2025-07-26 13:01:21 +02:00
parent 30c5a66cfb
commit 81bf9f40fc
8 changed files with 1096 additions and 1 deletions

74
drift-cleanup-daemon.js Normal file
View File

@@ -0,0 +1,74 @@
#!/usr/bin/env node
/**
* Drift Order Cleanup Daemon
* Runs the cleanup service in the background
*/
const { driftOrderCleanupService } = require('./lib/drift-order-cleanup-service.js')
let isShuttingDown = false
async function startDaemon() {
console.log('🚀 Starting Drift Order Cleanup Daemon...')
console.log('==========================================')
// Start the cleanup service
driftOrderCleanupService.start(60000) // Check every 60 seconds
console.log('✅ Daemon started successfully!')
console.log('📊 Monitoring for orphaned orders every 60 seconds')
console.log('🛑 Press Ctrl+C to stop')
console.log('')
// Set up graceful shutdown
process.on('SIGINT', gracefulShutdown)
process.on('SIGTERM', gracefulShutdown)
process.on('SIGQUIT', gracefulShutdown)
// Keep the process running
const keepAlive = setInterval(() => {
if (!isShuttingDown) {
const status = driftOrderCleanupService.getStatus()
const timestamp = new Date().toISOString()
console.log(`[${timestamp}] 💓 Daemon running - Last cleanup: ${status.lastCleanupTime ? `${Math.floor((Date.now() - status.lastCleanupTime) / 1000)}s ago` : 'Never'}`)
}
}, 300000) // Log status every 5 minutes
// Cleanup on exit
process.on('exit', () => {
clearInterval(keepAlive)
})
}
function gracefulShutdown(signal) {
if (isShuttingDown) return
isShuttingDown = true
console.log(`\n🛑 Received ${signal}, shutting down gracefully...`)
driftOrderCleanupService.stop()
console.log('✅ Drift order cleanup daemon stopped')
process.exit(0)
}
// Error handling
process.on('uncaughtException', (error) => {
console.error('❌ Uncaught exception:', error)
gracefulShutdown('UNCAUGHT_EXCEPTION')
})
process.on('unhandledRejection', (reason, promise) => {
console.error('❌ Unhandled rejection at:', promise, 'reason:', reason)
})
// Start the daemon
if (require.main === module) {
startDaemon().catch(error => {
console.error('❌ Failed to start daemon:', error)
process.exit(1)
})
}
module.exports = { startDaemon }