- Added fallback SL/TP calculation when AI values missing (rate limits) - Stop loss: 1.5% from entry (scalping-optimized) - Take profit: 3% from entry (2:1 risk/reward) - Relaxed API validation to require only stop loss (most critical) - Disabled problematic import in position-history route - System now guarantees risk management on every trade No more unprotected positions - works with or without AI analysis
118 lines
4.2 KiB
JavaScript
118 lines
4.2 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
// Quick script to place stop loss and take profit for scalping positions
|
|
|
|
async function placeScalpingSLTP() {
|
|
try {
|
|
console.log('🎯 Setting up scalping risk management...');
|
|
|
|
// First, get current position
|
|
const posResponse = await fetch('http://localhost:9001/api/drift/positions');
|
|
const posData = await posResponse.json();
|
|
|
|
if (!posData.positions || posData.positions.length === 0) {
|
|
console.log('❌ No active positions found');
|
|
return;
|
|
}
|
|
|
|
const position = posData.positions[0]; // Assuming SOL position
|
|
console.log('📊 Current position:', {
|
|
symbol: position.symbol,
|
|
size: position.size,
|
|
direction: position.direction,
|
|
entryPrice: position.entryPrice,
|
|
unrealizedPnl: position.unrealizedPnl
|
|
});
|
|
|
|
// Get current SOL price for calculations
|
|
const priceResponse = await fetch('http://localhost:9001/api/drift/balance');
|
|
const priceData = await priceResponse.json();
|
|
const currentPrice = parseFloat(position.markPrice || position.entryPrice);
|
|
|
|
console.log('💰 Current SOL price:', currentPrice);
|
|
|
|
// Scalping risk management (tight stops for quick profits)
|
|
const isLong = position.direction === 'LONG';
|
|
const positionSize = Math.abs(parseFloat(position.size));
|
|
|
|
// Scalping parameters (adjust these based on your risk tolerance)
|
|
const stopLossPercent = 0.5; // 0.5% stop loss (tight for scalping)
|
|
const takeProfitPercent = 1.0; // 1% take profit (1:2 risk/reward)
|
|
|
|
// Calculate SL and TP prices
|
|
let stopLossPrice, takeProfitPrice;
|
|
|
|
if (isLong) {
|
|
stopLossPrice = currentPrice * (1 - stopLossPercent / 100);
|
|
takeProfitPrice = currentPrice * (1 + takeProfitPercent / 100);
|
|
} else {
|
|
stopLossPrice = currentPrice * (1 + stopLossPercent / 100);
|
|
takeProfitPrice = currentPrice * (1 - takeProfitPercent / 100);
|
|
}
|
|
|
|
console.log('🎯 Calculated prices:', {
|
|
currentPrice: currentPrice.toFixed(3),
|
|
stopLoss: stopLossPrice.toFixed(3),
|
|
takeProfit: takeProfitPrice.toFixed(3),
|
|
slDistance: `${stopLossPercent}%`,
|
|
tpDistance: `${takeProfitPercent}%`
|
|
});
|
|
|
|
// Place Stop Loss order
|
|
console.log('🛑 Placing Stop Loss order...');
|
|
const slResponse = await fetch('http://localhost:9001/api/drift/place-order', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
symbol: 'SOL-PERP',
|
|
orderType: 'STOP_MARKET',
|
|
direction: isLong ? 'SHORT' : 'LONG', // Opposite direction to close position
|
|
size: positionSize,
|
|
triggerPrice: stopLossPrice,
|
|
reduceOnly: true
|
|
})
|
|
});
|
|
|
|
const slResult = await slResponse.json();
|
|
console.log('🛑 Stop Loss result:', slResult.success ? '✅ Placed' : '❌ Failed', slResult);
|
|
|
|
// Place Take Profit order
|
|
console.log('💰 Placing Take Profit order...');
|
|
const tpResponse = await fetch('http://localhost:9001/api/drift/place-order', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
symbol: 'SOL-PERP',
|
|
orderType: 'LIMIT',
|
|
direction: isLong ? 'SHORT' : 'LONG', // Opposite direction to close position
|
|
size: positionSize,
|
|
price: takeProfitPrice,
|
|
reduceOnly: true
|
|
})
|
|
});
|
|
|
|
const tpResult = await tpResponse.json();
|
|
console.log('💰 Take Profit result:', tpResult.success ? '✅ Placed' : '❌ Failed', tpResult);
|
|
|
|
// Verify orders were placed
|
|
console.log('📋 Checking placed orders...');
|
|
const ordersResponse = await fetch('http://localhost:9001/api/drift/orders');
|
|
const ordersData = await ordersResponse.json();
|
|
|
|
const reduceOnlyOrders = ordersData.orders?.filter(order => order.reduceOnly) || [];
|
|
console.log(`📊 Active reduce-only orders: ${reduceOnlyOrders.length}`);
|
|
|
|
reduceOnlyOrders.forEach(order => {
|
|
console.log(` - ${order.orderType} ${order.direction} at ${order.triggerPrice || order.price}`);
|
|
});
|
|
|
|
console.log('🎯 Scalping risk management setup complete!');
|
|
|
|
} catch (error) {
|
|
console.error('❌ Error setting up scalping SL/TP:', error.message);
|
|
}
|
|
}
|
|
|
|
// Run the function
|
|
placeScalpingSLTP();
|