Files
trading_bot_v3/app/api/automation/position-monitor/route.js
mindesbunister 167d7ff5bc feat: implement comprehensive AI decision display and reasoning panel
Major Features Added:
- Complete AI decision tracking system with detailed reasoning display
- Prominent gradient-styled AI reasoning panel on automation-v2 page
- Test AI decision generator with realistic trading scenarios
- Enhanced decision transparency showing entry/exit logic and leverage calculations

- Fixed orphaned order cleanup to preserve reduce-only SL/TP orders
- Integrated AI leverage calculator with 100x capability (up from 10x limit)
- Added lastDecision property to automation status for UI display
- Enhanced position monitoring with better cleanup triggers

- Beautiful gradient-styled AI Trading Analysis panel
- Color-coded confidence levels and recommendation displays
- Detailed breakdown of entry strategy, stop loss logic, and take profit targets
- Real-time display of AI leverage reasoning with safety buffer explanations
- Test AI button for demonstration of decision-making process

- SL/TP orders now execute properly (fixed cleanup interference)
- AI calculates sophisticated leverage (8.8x-42.2x vs previous 1x hardcoded)
- Complete decision audit trail with execution details
- Risk management transparency with liquidation safety calculations

- Why This Decision? - Prominent reasoning section
- Entry & Exit Strategy - Price levels with color coding
- AI Leverage Decision - Detailed calculation explanations
- Execution status with success/failure indicators
- Transaction IDs and comprehensive trade details

All systems now provide full transparency of AI decision-making process.
2025-07-26 22:41:55 +02:00

191 lines
7.3 KiB
JavaScript

import { NextResponse } from 'next/server';
export async function GET() {
try {
// Get current positions with real-time data
const baseUrl = process.env.INTERNAL_API_URL || 'http://localhost:3000';
const positionsResponse = await fetch(`${baseUrl}/api/drift/positions`, {
cache: 'no-store', // Force fresh data
headers: {
'Cache-Control': 'no-cache'
}
});
const positionsData = await positionsResponse.json();
// Use real-time price from Drift positions data
let currentPrice = 185.0; // Fallback price
const result = {
timestamp: new Date().toISOString(),
hasPosition: false,
position: null,
stopLossProximity: null,
riskLevel: 'NONE',
nextAction: 'No position to monitor',
recommendation: 'START_TRADING',
orphanedOrderCleanup: null
};
if (positionsData.success && positionsData.positions.length > 0) {
const position = positionsData.positions[0];
// Use real-time mark price from Drift
currentPrice = position.markPrice || position.entryPrice || currentPrice;
result.hasPosition = true;
result.position = {
symbol: position.symbol,
side: position.side,
size: position.size,
entryPrice: position.entryPrice,
currentPrice: currentPrice,
unrealizedPnl: position.unrealizedPnl,
notionalValue: position.notionalValue
};
// Calculate stop loss proximity (mock - you'd need actual SL from order data)
let stopLossPrice;
if (position.side === 'long') {
stopLossPrice = position.entryPrice * 0.95; // 5% below entry
} else {
stopLossPrice = position.entryPrice * 1.05; // 5% above entry
}
const distanceToSL = Math.abs(currentPrice - stopLossPrice) / currentPrice;
const proximityPercent = distanceToSL * 100;
result.stopLossProximity = {
stopLossPrice: stopLossPrice,
currentPrice: currentPrice,
distancePercent: proximityPercent.toFixed(2),
isNear: proximityPercent < 2.0 // Within 2% = NEAR
};
// Risk assessment
if (proximityPercent < 1.0) {
result.riskLevel = 'CRITICAL';
result.nextAction = 'IMMEDIATE ANALYSIS REQUIRED - Price very close to SL';
result.recommendation = 'EMERGENCY_ANALYSIS';
} else if (proximityPercent < 2.0) {
result.riskLevel = 'HIGH';
result.nextAction = 'Enhanced monitoring - Analyze within 5 minutes';
result.recommendation = 'URGENT_MONITORING';
} else if (proximityPercent < 5.0) {
result.riskLevel = 'MEDIUM';
result.nextAction = 'Regular monitoring - Check every 10 minutes';
result.recommendation = 'NORMAL_MONITORING';
} else {
result.riskLevel = 'LOW';
result.nextAction = 'Standard monitoring - Check every 30 minutes';
result.recommendation = 'RELAXED_MONITORING';
}
} else {
// NO POSITION DETECTED - Check for orphaned orders and cleanup
try {
// Check for any remaining orders when we have no positions
const ordersResponse = await fetch(`${baseUrl}/api/drift/orders`, {
cache: 'no-store',
headers: {
'Cache-Control': 'no-cache'
}
});
if (ordersResponse.ok) {
const ordersData = await ordersResponse.json();
const activeOrders = ordersData.orders || [];
if (activeOrders.length > 0) {
console.log('📋 No active positions detected - checking for truly orphaned orders...');
// Filter for truly orphaned orders (non-reduce-only orders without positions)
// Do NOT clean up reduce-only orders as these could be legitimate SL/TP from recently closed positions
const trulyOrphanedOrders = activeOrders.filter(order => !order.reduceOnly);
if (trulyOrphanedOrders.length > 0) {
console.log(`🎯 Found ${trulyOrphanedOrders.length} truly orphaned orders (non-reduce-only) - triggering cleanup...`);
// Trigger automated cleanup of truly orphaned orders only
const cleanupResponse = await fetch(`${baseUrl}/api/drift/cleanup-orders`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
});
let cleanupResult = null;
if (cleanupResponse.ok) {
cleanupResult = await cleanupResponse.json();
if (cleanupResult.success) {
console.log('✅ Orphaned order cleanup completed:', cleanupResult.summary);
result.orphanedOrderCleanup = {
triggered: true,
success: true,
summary: cleanupResult.summary,
message: `Cleaned up ${cleanupResult.summary.totalCanceled} truly orphaned orders`
};
result.nextAction = `Cleaned up ${cleanupResult.summary.totalCanceled} orphaned orders - Ready for new trade`;
} else {
console.error('❌ Orphaned order cleanup failed:', cleanupResult.error);
result.orphanedOrderCleanup = {
triggered: true,
success: false,
error: cleanupResult.error,
message: 'Cleanup failed - Manual intervention may be needed'
};
result.nextAction = 'Cleanup failed - Check orders manually';
}
} else {
console.error('❌ Failed to trigger cleanup API');
result.orphanedOrderCleanup = {
triggered: false,
success: false,
error: 'Cleanup API unavailable',
message: 'Could not trigger automatic cleanup'
};
}
} else {
// All orders are reduce-only (likely SL/TP) - do not clean up
console.log('✅ All remaining orders are reduce-only (likely SL/TP) - skipping cleanup to preserve risk management');
result.orphanedOrderCleanup = {
triggered: false,
success: true,
message: 'All orders are reduce-only (SL/TP) - preserved for risk management'
};
}
} else {
// Only log occasionally when no orders found (not every check)
result.orphanedOrderCleanup = {
triggered: false,
success: true,
message: 'No orphaned orders detected'
};
}
}
} catch (cleanupError) {
console.error('❌ Error during orphaned order check:', cleanupError);
result.orphanedOrderCleanup = {
triggered: false,
success: false,
error: cleanupError.message,
message: 'Error checking for orphaned orders'
};
}
}
return NextResponse.json({
success: true,
monitor: result
});
} catch (error) {
console.error('Position monitor error:', error);
return NextResponse.json({
success: false,
error: 'Failed to get position monitoring data',
message: error.message
}, { status: 500 });
}
}