diff --git a/app/api/drift/balance/route.js b/app/api/drift/balance/route.js index cdd338d..5d79dc2 100644 --- a/app/api/drift/balance/route.js +++ b/app/api/drift/balance/route.js @@ -83,17 +83,28 @@ export async function GET() { }) } - // Process perp positions + // Process perp positions and calculate P&L properly const activePositions = perpPositions.filter(pos => pos.baseAssetAmount && !pos.baseAssetAmount.isZero() ) for (const position of activePositions) { - const baseAmount = Number(position.baseAssetAmount) / 1e9 // Convert from lamports - const quoteAmount = Number(position.quoteAssetAmount) / 1e6 // Convert from micro-USDC + const baseAmount = Number(position.baseAssetAmount) / 1e9 // Convert from lamports to SOL + const quoteAmount = Number(position.quoteAssetAmount) / 1e6 // Convert from micro-USDC to USDC - unrealizedPnl += quoteAmount - marginRequirement += Math.abs(baseAmount * 100) // Simplified margin calculation + // For P&L calculation: negative quoteAmount means we paid out USD to open position + // Positive means we received USD (short position) + const positionValue = Math.abs(baseAmount * 195) // Approximate current SOL price + const entryValue = Math.abs(quoteAmount) + + // Calculate unrealized P&L based on position direction + if (baseAmount > 0) { // Long position + unrealizedPnl += positionValue - entryValue + } else { // Short position + unrealizedPnl += entryValue - positionValue + } + + marginRequirement += positionValue * 0.1 // 10% margin requirement for perps } // Calculate free collateral (simplified) diff --git a/app/api/drift/trade/route.js b/app/api/drift/trade/route.js index d91f454..443ff17 100644 --- a/app/api/drift/trade/route.js +++ b/app/api/drift/trade/route.js @@ -106,8 +106,8 @@ export async function POST(request) { leverage = 1, stopLoss = true, takeProfit = true, - riskPercent = 2, - takeProfitPercent = 4 + stopLossPercent = 2, // Default 2% + takeProfitPercent = 4 // Default 4% } = await request.json() // Import Drift SDK components @@ -210,7 +210,7 @@ export async function POST(request) { } } else { try { - const { OrderType, PositionDirection } = await import('@drift-labs/sdk') + const { OrderType, PositionDirection, OrderTriggerCondition } = await import('@drift-labs/sdk') const BN = (await import('bn.js')).default const marketIndex = getMarketIndex(symbol) @@ -221,13 +221,19 @@ export async function POST(request) { console.log(`📊 Current ${symbol} price: $${currentPrice}`) - // For perpetual futures: amount is USD position size, convert to base asset amount - // Example: $32 position at $197.87/SOL = 0.162 SOL base asset amount - const solTokenAmount = amount / currentPrice + // For perpetual futures: amount is USD position size, apply leverage + // Example: $32 position with 10x leverage = $320 position value + const leveragedPositionSize = amount * leverage + console.log(`💰 Applying ${leverage}x leverage: $${amount} → $${leveragedPositionSize}`) + + // Convert leveraged USD position to SOL base asset amount + const solTokenAmount = leveragedPositionSize / currentPrice const baseAssetAmount = new BN(Math.floor(solTokenAmount * 1e9)) console.log(`💰 Position size conversion:`, { usdPositionSize: amount, + leverage: leverage, + leveragedPositionSize: leveragedPositionSize, solPrice: currentPrice, solTokenAmount: solTokenAmount, calculatedBaseAsset: solTokenAmount * 1e9, @@ -264,41 +270,48 @@ export async function POST(request) { await new Promise(resolve => setTimeout(resolve, 5000)) // 2. Calculate stop loss and take profit prices using config percentages - const stopLossPercent = Math.max(riskPercent / 100, 0.02) // Use riskPercent from config, minimum 2% - const takeProfitPercentCalc = Math.max(takeProfitPercent / 100, 0.04) // Use takeProfitPercent from config, minimum 4% + const stopLossPercentCalc = Math.max(stopLossPercent / 100, 0.03) // Use stopLossPercent from config, minimum 3% + const takeProfitPercentCalc = Math.max(takeProfitPercent / 100, 0.01) // Use takeProfitPercent from config, minimum 1% let stopLossPrice, takeProfitPrice if (direction === PositionDirection.LONG) { - stopLossPrice = currentPrice * (1 - stopLossPercent) + stopLossPrice = currentPrice * (1 - stopLossPercentCalc) takeProfitPrice = currentPrice * (1 + takeProfitPercentCalc) } else { - stopLossPrice = currentPrice * (1 + stopLossPercent) + stopLossPrice = currentPrice * (1 + stopLossPercentCalc) takeProfitPrice = currentPrice * (1 - takeProfitPercentCalc) } console.log(`🎯 Risk management:`, { stopLossPrice: stopLossPrice.toFixed(4), takeProfitPrice: takeProfitPrice.toFixed(4), - stopLossPercent: `${stopLossPercent * 100}%`, + stopLossPercent: `${stopLossPercentCalc * 100}%`, takeProfitPercent: `${takeProfitPercentCalc * 100}%`, priceDifference: Math.abs(currentPrice - stopLossPrice).toFixed(4) }) let stopLossTx = null, takeProfitTx = null - // 3. Place stop loss order + // 3. Place stop loss order if (stopLoss) { try { console.log('🛡️ Placing stop loss order...') const stopLossTriggerPrice = new BN(Math.floor(stopLossPrice * 1e6)) - const stopLossOrderPrice = new BN(Math.floor(stopLossPrice * 0.995 * 1e6)) // 0.5% slippage buffer + + const stopLossOrderPrice = direction === PositionDirection.LONG + ? new BN(Math.floor(stopLossPrice * 0.995 * 1e6)) // LONG: order below trigger + : new BN(Math.floor(stopLossPrice * 1.005 * 1e6)) // SHORT: order above trigger console.log(`🛡️ Stop Loss Details:`, { + orderType: 'TRIGGER_LIMIT', triggerPrice: (stopLossTriggerPrice.toNumber() / 1e6).toFixed(4), orderPrice: (stopLossOrderPrice.toNumber() / 1e6).toFixed(4), - baseAssetAmount: baseAssetAmount.toString() + direction: direction === PositionDirection.LONG ? 'SHORT' : 'LONG', + baseAssetAmount: baseAssetAmount.toString(), + currentPrice: currentPrice, + stopLossPrice: stopLossPrice }) stopLossTx = await driftClient.placePerpOrder({ @@ -308,18 +321,19 @@ export async function POST(request) { baseAssetAmount, price: stopLossOrderPrice, triggerPrice: stopLossTriggerPrice, + triggerCondition: direction === PositionDirection.LONG ? OrderTriggerCondition.BELOW : OrderTriggerCondition.ABOVE, reduceOnly: true, }) console.log('✅ Stop loss placed:', stopLossTx) } catch (slError) { console.warn('⚠️ Stop loss failed:', slError.message) - // Log more details about the stop loss failure console.warn('🛡️ Stop loss failure details:', { stopLossPrice, currentPrice, priceDiff: Math.abs(currentPrice - stopLossPrice), - percentDiff: ((Math.abs(currentPrice - stopLossPrice) / currentPrice) * 100).toFixed(2) + '%' + percentDiff: ((Math.abs(currentPrice - stopLossPrice) / currentPrice) * 100).toFixed(2) + '%', + error: slError.message }) } } @@ -378,7 +392,8 @@ export async function POST(request) { riskManagement: { stopLoss: !!stopLossTx, takeProfit: !!takeProfitTx, - riskPercent + stopLossPercent, + takeProfitPercent }, position: position ? { marketIndex: position.marketIndex, diff --git a/prisma/prisma/dev.db b/prisma/prisma/dev.db index 3dd4b32..50fc492 100644 Binary files a/prisma/prisma/dev.db and b/prisma/prisma/dev.db differ