feat: Complete AI Learning Integration & Position Scaling DCA System
- Integrated SimplifiedStopLossLearner into automation - Every AI decision now recorded for learning (stop loss, take profit, confidence) - Trade outcomes tracked and compared to AI predictions - Learning patterns improve future AI decisions - Enhanced status dashboard with learning insights - Proper DCA: increase position size + adjust existing SL/TP (not create new) - AI-calculated optimal levels for scaled positions - Prevents order fragmentation (fixes 24+ order problem) - Unified risk management for entire scaled position TIMEFRAME-AWARE INTERVALS: - Scalping (5m/15m): 5-15 minute analysis intervals - Day Trading (1h/4h): 10-30 minute intervals - Swing Trading (4h/1d): 23-68 minute intervals - Perfect for 5-minute scalping with DCA protection - 2-hour DCA cooldown prevents order spam - Position existence checks before new trades - Direction matching validation - Learning-based decision improvements - AI calculates ALL levels (entry, SL, TP, leverage, scaling) - Every calculation recorded and learned from - Position scaling uses AI intelligence - Timeframe-appropriate analysis frequency - Professional order management - Continuous learning and improvement ADDRESSES ALL USER CONCERNS: - 5-minute scalping compatibility ✅ - Position scaling DCA (adjust existing SL/TP) ✅ - AI calculations being learned from ✅ - No order fragmentation ✅ - Intelligent automation with learning ✅ Files: automation, consolidation APIs, learning integration, tests, documentation
This commit is contained in:
133
app/api/drift/place-order/route.js
Normal file
133
app/api/drift/place-order/route.js
Normal file
@@ -0,0 +1,133 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
|
||||
export async function POST(request) {
|
||||
try {
|
||||
const body = await request.json();
|
||||
const {
|
||||
symbol,
|
||||
orderType,
|
||||
direction,
|
||||
size,
|
||||
price,
|
||||
triggerPrice,
|
||||
reduceOnly = true
|
||||
} = body;
|
||||
|
||||
console.log('📝 Placing consolidated order:', {
|
||||
symbol,
|
||||
orderType,
|
||||
direction,
|
||||
size,
|
||||
price,
|
||||
triggerPrice,
|
||||
reduceOnly
|
||||
});
|
||||
|
||||
// Import Drift SDK
|
||||
const { DriftClient, initialize, MarketType, PositionDirection, OrderType, OrderTriggerCondition, Wallet, BN } = await import('@drift-labs/sdk');
|
||||
const { Connection, Keypair } = await import('@solana/web3.js');
|
||||
|
||||
// Setup connection and wallet
|
||||
const rpcEndpoint = process.env.SOLANA_RPC_URL || 'https://mainnet.helius-rpc.com/?api-key=5e236449-f936-4af7-ae38-f15e2f1a3757';
|
||||
const connection = new Connection(rpcEndpoint, 'confirmed');
|
||||
|
||||
if (!process.env.SOLANA_PRIVATE_KEY) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: 'SOLANA_PRIVATE_KEY not configured'
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
const privateKeyArray = JSON.parse(process.env.SOLANA_PRIVATE_KEY);
|
||||
const keypair = Keypair.fromSecretKey(new Uint8Array(privateKeyArray));
|
||||
const wallet = new Wallet(keypair);
|
||||
|
||||
// Initialize Drift client
|
||||
const env = 'mainnet-beta';
|
||||
const sdkConfig = initialize({ env });
|
||||
const driftClient = new DriftClient({
|
||||
connection,
|
||||
wallet,
|
||||
programID: sdkConfig.DRIFT_PROGRAM_ID,
|
||||
accountSubscription: {
|
||||
type: 'polling',
|
||||
accountLoader: {
|
||||
commitment: 'confirmed'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
await driftClient.subscribe();
|
||||
|
||||
// Map symbol to market index
|
||||
const marketIndex = symbol === 'SOL-PERP' ? 0 : 1; // SOL-PERP is market 0
|
||||
|
||||
// Convert direction to Drift enum
|
||||
const driftDirection = direction.toUpperCase() === 'LONG' || direction.toUpperCase() === 'BUY'
|
||||
? PositionDirection.LONG
|
||||
: PositionDirection.SHORT;
|
||||
|
||||
// Convert size to base asset amount (multiply by 1e9 for SOL)
|
||||
const baseAssetAmount = new BN(Math.floor(parseFloat(size) * 1e9));
|
||||
|
||||
// Determine trigger condition based on current price and trigger price
|
||||
const currentPrice = parseFloat(price);
|
||||
const trigger = parseFloat(triggerPrice);
|
||||
const triggerCondition = driftDirection === PositionDirection.SHORT
|
||||
? (trigger > currentPrice ? OrderTriggerCondition.ABOVE : OrderTriggerCondition.BELOW)
|
||||
: (trigger > currentPrice ? OrderTriggerCondition.ABOVE : OrderTriggerCondition.BELOW);
|
||||
|
||||
// Create order parameters
|
||||
const orderParams = {
|
||||
orderType: OrderType.TRIGGER_LIMIT,
|
||||
marketType: MarketType.PERP,
|
||||
direction: driftDirection,
|
||||
baseAssetAmount: baseAssetAmount,
|
||||
price: new BN(Math.floor(currentPrice * 1e6)), // Price in 6 decimal format
|
||||
marketIndex: marketIndex,
|
||||
triggerPrice: new BN(Math.floor(trigger * 1e6)),
|
||||
triggerCondition: triggerCondition,
|
||||
reduceOnly: reduceOnly,
|
||||
};
|
||||
|
||||
console.log('🎯 Placing Drift order with params:', {
|
||||
orderType: 'TRIGGER_LIMIT',
|
||||
direction: driftDirection === PositionDirection.LONG ? 'LONG' : 'SHORT',
|
||||
size: size,
|
||||
price: currentPrice,
|
||||
triggerPrice: trigger,
|
||||
triggerCondition: triggerCondition === OrderTriggerCondition.ABOVE ? 'ABOVE' : 'BELOW'
|
||||
});
|
||||
|
||||
// Place the order
|
||||
const txSig = await driftClient.placePerpOrder(orderParams);
|
||||
|
||||
await driftClient.unsubscribe();
|
||||
|
||||
console.log('✅ Consolidated order placed:', txSig);
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: 'Order placed successfully',
|
||||
orderId: txSig,
|
||||
txSignature: txSig,
|
||||
orderParams: {
|
||||
symbol,
|
||||
orderType,
|
||||
direction,
|
||||
size,
|
||||
price,
|
||||
triggerPrice,
|
||||
reduceOnly
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Place order error:', error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: 'Failed to place order',
|
||||
details: error.message
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user