feat: Remove artificial percentage minimums - AI now has complete freedom

REMOVED ARTIFICIAL CONSTRAINTS:
- Eliminated 3% minimum stop loss requirement
- Eliminated 1% minimum take profit requirement
- AI can now choose ANY percentage based on market analysis

- Updated app/api/drift/trade/route.js to use exact AI percentages
- Removed Math.max() constraints that forced minimums
- AI now has 0.1%+ to 50%+ percentage freedom

- Modified AI_RISK_MANAGEMENT.md to reflect new freedom
- Removed all references to artificial 3%/1% minimums
- Added ultra-tight scalping examples (0.1%-1%)
- Updated volatility guidelines for all trading styles

 PROVEN WITH REAL ORDERS:
- Transaction: 35QmCqWFzwJ1X2nm5M8rgExKEMbWTRqxCa1GryEsR595zYwBLqCzDowUYm3J2u13WMvYR2PRoS3eAMSzXfGvEVbe
- Confirmed: 0.5% SL / 0.25% TP working on Drift Protocol
- Verified: Orders visible in Drift UI with correct trigger prices

- Optimal risk management based on actual market conditions
- Support for all trading styles: scalping to position trading
- No more forced suboptimal stops due to artificial limits
- Professional-grade percentage precision

The AI can now freely optimize percentages for maximum trading effectiveness!
This commit is contained in:
mindesbunister
2025-07-24 09:58:30 +02:00
parent e7dc60b427
commit 9c4bee0dd7
17 changed files with 3649 additions and 733 deletions

332
test-drift-real-orders.js Normal file
View File

@@ -0,0 +1,332 @@
#!/usr/bin/env node
/**
* REAL DRIFT PROTOCOL MINIMUM PERCENTAGE TEST
*
* This test places ACTUAL small orders on Drift Protocol to validate
* that the reduced minimum percentages work in real trading conditions.
*
* SAFETY MEASURES:
* - Uses very small position sizes ($0.50 - $2.00)
* - Tests on SOL-PERP with high liquidity
* - Automatically cancels test orders after validation
* - Monitors for order rejection reasons
*/
const https = require('https');
const http = require('http');
// Test configuration
const API_BASE = 'http://localhost:3000/api';
const TEST_SYMBOL = 'SOLUSD';
const TEST_AMOUNT = 0.5; // $0.50 position size for safety
// Minimum percentages to test (progressively tighter)
const TEST_CASES = [
{ sl: 1.5, tp: 1.0, desc: 'Conservative scalping (1.5%/1.0%)' },
{ sl: 1.0, tp: 0.75, desc: 'Moderate scalping (1.0%/0.75%)' },
{ sl: 0.75, tp: 0.5, desc: 'Tight scalping (0.75%/0.5%)' },
{ sl: 0.5, tp: 0.25, desc: 'Ultra-tight scalping (0.5%/0.25%)' },
{ sl: 0.25, tp: 0.1, desc: 'Extreme scalping (0.25%/0.1%)' }
];
async function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function makeApiCall(endpoint, method = 'GET', body = null) {
return new Promise((resolve, reject) => {
const url = `http://localhost:3000/api${endpoint}`;
const parsedUrl = new URL(url);
const options = {
hostname: parsedUrl.hostname,
port: parsedUrl.port,
path: parsedUrl.pathname + parsedUrl.search,
method: method,
headers: {
'Content-Type': 'application/json',
},
};
const req = http.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
try {
const jsonData = JSON.parse(data);
resolve({ success: res.statusCode >= 200 && res.statusCode < 300, data: jsonData, status: res.statusCode });
} catch (error) {
resolve({ success: false, error: `Parse error: ${error.message}`, data: data });
}
});
});
req.on('error', (error) => {
resolve({ success: false, error: error.message });
});
if (body) {
req.write(JSON.stringify(body));
}
req.end();
});
}
async function getCurrentBalance() {
console.log('💰 Checking current Drift balance...');
const result = await makeApiCall('/drift/balance');
if (!result.success) {
throw new Error(`Failed to get balance: ${result.error}`);
}
console.log(` Balance: $${result.data.totalCollateral}`);
console.log(` Available: $${result.data.availableBalance}`);
return parseFloat(result.data.availableBalance);
}
async function getCurrentPositions() {
console.log('📋 Checking current positions...');
const result = await makeApiCall('/drift/positions');
if (!result.success) {
throw new Error(`Failed to get positions: ${result.error}`);
}
console.log(` Active positions: ${result.data.positions.length}`);
return result.data.positions;
}
async function testOrderPlacement(testCase, entryPrice) {
console.log(`\n🔬 Testing: ${testCase.desc}`);
console.log(` Entry: $${entryPrice.toFixed(4)}`);
console.log(` Stop Loss: ${testCase.sl}% (${(entryPrice * (1 - testCase.sl/100)).toFixed(4)})`);
console.log(` Take Profit: ${testCase.tp}% (${(entryPrice * (1 + testCase.tp/100)).toFixed(4)})`);
// Calculate position size based on test amount
const positionSize = TEST_AMOUNT / entryPrice;
const tradeRequest = {
symbol: TEST_SYMBOL,
side: 'long',
amount: positionSize.toFixed(6),
stopLossPercent: testCase.sl,
takeProfitPercent: testCase.tp,
leverage: 1, // Conservative leverage for testing
orderType: 'market'
};
console.log(` Position size: ${positionSize.toFixed(6)} SOL ($${TEST_AMOUNT})`);
try {
// Place the order
console.log(' 📤 Placing order...');
const result = await makeApiCall('/drift/trade', 'POST', tradeRequest);
if (result.success) {
console.log(` ✅ SUCCESS: Order placed with ${testCase.sl}%/${testCase.tp}% levels`);
console.log(` 📋 Transaction: ${result.data.signature || 'N/A'}`);
// Wait a moment for order to process
await delay(2000);
// Check if position was created
const positions = await getCurrentPositions();
const newPosition = positions.find(p => p.symbol === TEST_SYMBOL);
if (newPosition) {
console.log(` 💼 Position created: ${newPosition.size} SOL`);
console.log(` 🎯 Stop Loss: $${newPosition.stopLoss || 'N/A'}`);
console.log(` 📈 Take Profit: $${newPosition.takeProfit || 'N/A'}`);
// IMPORTANT: Close the test position immediately
console.log(' 🧹 Closing test position...');
const closeResult = await makeApiCall('/drift/trade', 'POST', {
symbol: TEST_SYMBOL,
side: 'sell',
amount: Math.abs(parseFloat(newPosition.size)),
orderType: 'market'
});
if (closeResult.success) {
console.log(' ✅ Test position closed successfully');
} else {
console.log(` ⚠️ Warning: Could not close position: ${closeResult.error}`);
}
}
return { success: true, details: result.data };
} else {
console.log(` ❌ FAILED: ${result.data.error || result.error}`);
// Analyze the failure reason
const errorMsg = result.data.error || result.error || '';
if (errorMsg.includes('trigger') || errorMsg.includes('price')) {
console.log(` 🔍 Analysis: Price level too close to market`);
return { success: false, reason: 'price_too_close' };
} else if (errorMsg.includes('margin') || errorMsg.includes('collateral')) {
console.log(` 🔍 Analysis: Insufficient margin/collateral`);
return { success: false, reason: 'insufficient_margin' };
} else {
console.log(` 🔍 Analysis: Other error - ${errorMsg}`);
return { success: false, reason: 'other', error: errorMsg };
}
}
} catch (error) {
console.log(` ❌ EXCEPTION: ${error.message}`);
return { success: false, reason: 'exception', error: error.message };
}
}
async function getCurrentPrice() {
console.log('📊 Getting current SOL price...');
return new Promise((resolve, reject) => {
const options = {
hostname: 'api.binance.com',
port: 443,
path: '/api/v3/ticker/price?symbol=SOLUSDT',
method: 'GET',
};
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
try {
const jsonData = JSON.parse(data);
const price = parseFloat(jsonData.price);
console.log(` SOL Price: $${price.toFixed(4)}`);
resolve(price);
} catch (error) {
console.log(` ⚠️ Could not parse price data: ${error.message}`);
console.log(' Using fallback price: $200.00');
resolve(200.00);
}
});
});
req.on('error', (error) => {
console.log(` ⚠️ Could not get price from Binance: ${error.message}`);
console.log(' Using fallback price: $200.00');
resolve(200.00);
});
req.end();
});
}
async function runRealDriftTest() {
console.log('🚀 REAL DRIFT PROTOCOL MINIMUM PERCENTAGE TEST');
console.log('=' .repeat(60));
console.log('⚠️ WARNING: This test places REAL orders with REAL money');
console.log('💡 Position size limited to $0.50 for safety');
console.log('🧹 Test positions are automatically closed');
console.log('=' .repeat(60));
try {
// Pre-flight checks
const balance = await getCurrentBalance();
if (balance < 10) {
throw new Error(`Insufficient balance: $${balance}. Minimum $10 required for safe testing.`);
}
const initialPositions = await getCurrentPositions();
const entryPrice = await getCurrentPrice();
// Run tests
console.log('\n📋 Test Results Summary:');
console.log('-' .repeat(60));
const results = [];
for (const testCase of TEST_CASES) {
const result = await testOrderPlacement(testCase, entryPrice);
results.push({ ...testCase, ...result });
// Wait between tests to avoid rate limits
await delay(3000);
}
// Analysis
console.log('\n🎯 FINAL ANALYSIS:');
console.log('=' .repeat(60));
const successful = results.filter(r => r.success);
const failed = results.filter(r => !r.success);
console.log(`✅ Successful: ${successful.length}/${results.length} test cases`);
console.log(`❌ Failed: ${failed.length}/${results.length} test cases`);
if (successful.length > 0) {
const tightest = successful[successful.length - 1];
console.log(`\n🏆 TIGHTEST WORKING PERCENTAGES:`);
console.log(` Stop Loss: ${tightest.sl}%`);
console.log(` Take Profit: ${tightest.tp}%`);
console.log(` Description: ${tightest.desc}`);
console.log(`\n💡 RECOMMENDED NEW MINIMUMS:`);
console.log(` stopLossPercentCalc = Math.max(stopLossPercent / 100, ${(tightest.sl / 100).toFixed(4)}) // ${tightest.sl}%`);
console.log(` takeProfitPercentCalc = Math.max(takeProfitPercent / 100, ${(tightest.tp / 100).toFixed(4)}) // ${tightest.tp}%`);
}
if (failed.length > 0) {
console.log(`\n⚠️ FAILURES ANALYSIS:`);
failed.forEach(f => {
console.log(` ${f.desc}: ${f.reason}`);
});
}
// Final position check
console.log('\n🧹 POST-TEST CLEANUP CHECK:');
const finalPositions = await getCurrentPositions();
const newPositions = finalPositions.length - initialPositions.length;
if (newPositions > 0) {
console.log(`⚠️ Warning: ${newPositions} test positions remain open`);
console.log(' Manual cleanup may be required');
} else {
console.log('✅ All test positions cleaned up successfully');
}
const finalBalance = await getCurrentBalance();
const balanceChange = finalBalance - balance;
console.log(`💰 Balance change: ${balanceChange >= 0 ? '+' : ''}$${balanceChange.toFixed(2)}`);
} catch (error) {
console.error('❌ Test failed:', error.message);
console.log('\n This could be due to:');
console.log(' - Network connectivity issues');
console.log(' - Drift Protocol API changes');
console.log(' - Insufficient balance or margin');
console.log(' - Market conditions (low liquidity)');
}
}
// Safety confirmation
console.log('⚠️ SAFETY CONFIRMATION REQUIRED ⚠️');
console.log('This test will place REAL orders on Drift Protocol');
console.log('Position size is limited to $0.50 per test');
console.log('Orders will be automatically closed');
console.log('');
console.log('To proceed, run: node test-drift-real-orders.js --confirm');
if (process.argv.includes('--confirm')) {
runRealDriftTest();
} else {
console.log('Test not run - confirmation required');
process.exit(0);
}