feat: fix AI Trading Analysis panel to show real successful trade data
Fixed analysis-details API to use exact same logic as position-history Now shows successful .13 WIN trade instead of old mock data Successful trade sync script working correctly Position monitor shows active SHORT position with proper stop-loss Next: Complete risk management system integration
This commit is contained in:
153
app/api/automation/place-risk-management/route.js
Normal file
153
app/api/automation/place-risk-management/route.js
Normal file
@@ -0,0 +1,153 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
|
||||
export async function POST(request) {
|
||||
try {
|
||||
const body = await request.json();
|
||||
const { symbol, action } = body;
|
||||
|
||||
console.log('🛡️ Risk Management Request:', { symbol, action });
|
||||
|
||||
// Get current position first
|
||||
const positionResponse = await fetch(`${process.env.INTERNAL_API_URL || 'http://localhost:9001'}/api/automation/position-monitor`);
|
||||
const positionData = await positionResponse.json();
|
||||
|
||||
if (!positionData.success || !positionData.monitor.hasPosition) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: 'No active position found'
|
||||
});
|
||||
}
|
||||
|
||||
const position = positionData.monitor.position;
|
||||
console.log('📊 Current position:', position);
|
||||
|
||||
// Calculate proper stop-loss and take-profit levels
|
||||
const entryPrice = position.entryPrice;
|
||||
const currentPrice = position.currentPrice;
|
||||
const size = position.size;
|
||||
const side = position.side; // 'short' or 'long'
|
||||
|
||||
let stopLossPrice, takeProfitPrice;
|
||||
|
||||
if (side.toLowerCase() === 'short') {
|
||||
// For SHORT positions:
|
||||
// Stop-loss: BUY above entry price (limit losses)
|
||||
// Take-profit: BUY below current price (secure profits)
|
||||
stopLossPrice = entryPrice * 1.025; // 2.5% above entry
|
||||
takeProfitPrice = currentPrice * 0.985; // 1.5% below current (secure profits)
|
||||
} else {
|
||||
// For LONG positions:
|
||||
// Stop-loss: SELL below entry price (limit losses)
|
||||
// Take-profit: SELL above current price (secure profits)
|
||||
stopLossPrice = entryPrice * 0.975; // 2.5% below entry
|
||||
takeProfitPrice = currentPrice * 1.015; // 1.5% above current
|
||||
}
|
||||
|
||||
const orders = [];
|
||||
|
||||
// Place stop-loss order
|
||||
try {
|
||||
const stopLossOrder = {
|
||||
symbol: symbol,
|
||||
side: side.toLowerCase() === 'short' ? 'BUY' : 'SELL',
|
||||
amount: size,
|
||||
orderType: 'TRIGGER_LIMIT',
|
||||
triggerPrice: stopLossPrice,
|
||||
limitPrice: side.toLowerCase() === 'short' ? stopLossPrice * 1.002 : stopLossPrice * 0.998,
|
||||
reduceOnly: true
|
||||
};
|
||||
|
||||
console.log('🛑 Placing stop-loss order:', stopLossOrder);
|
||||
|
||||
const slResponse = await fetch(`${process.env.INTERNAL_API_URL || 'http://localhost:9001'}/api/drift/place-order`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(stopLossOrder)
|
||||
});
|
||||
|
||||
const slResult = await slResponse.json();
|
||||
orders.push({
|
||||
type: 'stop-loss',
|
||||
success: slResult.success,
|
||||
price: stopLossPrice,
|
||||
orderId: slResult.orderId,
|
||||
error: slResult.error
|
||||
});
|
||||
|
||||
} catch (slError) {
|
||||
orders.push({
|
||||
type: 'stop-loss',
|
||||
success: false,
|
||||
error: slError.message
|
||||
});
|
||||
}
|
||||
|
||||
// Place take-profit order
|
||||
try {
|
||||
const takeProfitOrder = {
|
||||
symbol: symbol,
|
||||
side: side.toLowerCase() === 'short' ? 'BUY' : 'SELL',
|
||||
amount: size,
|
||||
orderType: 'TRIGGER_LIMIT',
|
||||
triggerPrice: takeProfitPrice,
|
||||
limitPrice: side.toLowerCase() === 'short' ? takeProfitPrice * 0.998 : takeProfitPrice * 1.002,
|
||||
reduceOnly: true
|
||||
};
|
||||
|
||||
console.log('🎯 Placing take-profit order:', takeProfitOrder);
|
||||
|
||||
const tpResponse = await fetch(`${process.env.INTERNAL_API_URL || 'http://localhost:9001'}/api/drift/place-order`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(takeProfitOrder)
|
||||
});
|
||||
|
||||
const tpResult = await tpResponse.json();
|
||||
orders.push({
|
||||
type: 'take-profit',
|
||||
success: tpResult.success,
|
||||
price: takeProfitPrice,
|
||||
orderId: tpResult.orderId,
|
||||
error: tpResult.error
|
||||
});
|
||||
|
||||
} catch (tpError) {
|
||||
orders.push({
|
||||
type: 'take-profit',
|
||||
success: false,
|
||||
error: tpError.message
|
||||
});
|
||||
}
|
||||
|
||||
const successfulOrders = orders.filter(o => o.success);
|
||||
const failedOrders = orders.filter(o => !o.success);
|
||||
|
||||
return NextResponse.json({
|
||||
success: successfulOrders.length > 0,
|
||||
message: `Risk management: ${successfulOrders.length} orders placed, ${failedOrders.length} failed`,
|
||||
position: {
|
||||
symbol: position.symbol,
|
||||
side: position.side,
|
||||
size: position.size,
|
||||
entryPrice: position.entryPrice,
|
||||
currentPrice: position.currentPrice,
|
||||
unrealizedPnl: position.unrealizedPnl
|
||||
},
|
||||
orders: orders,
|
||||
riskManagement: {
|
||||
stopLossPrice: stopLossPrice.toFixed(4),
|
||||
takeProfitPrice: takeProfitPrice.toFixed(4),
|
||||
riskPercent: side.toLowerCase() === 'short' ? '+2.5%' : '-2.5%',
|
||||
rewardPercent: side.toLowerCase() === 'short' ? '-1.5%' : '+1.5%'
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Risk management error:', error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: 'Failed to place risk management orders',
|
||||
details: error.message
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user