#!/usr/bin/env node /** * Update Open Positions - Calculate current P&L for EXECUTED trades */ const { PrismaClient } = require('@prisma/client'); async function getCurrentSOLPrice() { try { const response = await fetch('https://api.coingecko.com/api/v3/simple/price?ids=solana&vs_currencies=usd'); const data = await response.json(); return data.solana.usd; } catch (error) { console.warn('Could not fetch current SOL price, using fallback'); return 185; // Fallback price based on recent data } } async function updateOpenPositions() { const prisma = new PrismaClient(); try { console.log('šŸ”§ Updating open positions with current market data...'); const currentPrice = await getCurrentSOLPrice(); console.log(`šŸ“Š Current SOL price: $${currentPrice}`); // Get EXECUTED trades that are still "open" const openTrades = await prisma.trades.findMany({ where: { status: 'EXECUTED', profit: null, // No profit calculated yet entryPrice: { not: null } // Must have entry price }, orderBy: { createdAt: 'desc' } }); console.log(`šŸ“‹ Found ${openTrades.length} open trades to update`); let updated = 0; let totalPnl = 0; for (const trade of openTrades) { try { const entryPrice = trade.entryPrice; const amount = trade.amount; const side = trade.side.toLowerCase(); // Calculate P&L based on current price let pnl = 0; let outcome = 'UNKNOWN'; if (side === 'buy' || side === 'long') { // Long position: profit when price goes up pnl = (currentPrice - entryPrice) * amount; outcome = currentPrice > entryPrice ? 'WIN' : 'LOSS'; } else if (side === 'sell' || side === 'short') { // Short position: profit when price goes down pnl = (entryPrice - currentPrice) * amount; outcome = currentPrice < entryPrice ? 'WIN' : 'LOSS'; } const pnlPercent = (pnl / (entryPrice * amount)) * 100; // Update the trade await prisma.trades.update({ where: { id: trade.id }, data: { status: 'COMPLETED', // Mark as completed profit: pnl, pnlPercent: pnlPercent, outcome: outcome, exitPrice: currentPrice, closedAt: new Date(), // Mark as closed now updatedAt: new Date() } }); updated++; totalPnl += pnl; if (updated <= 5) { console.log(`āœ… Updated: ${trade.id} - ${side} ${amount} SOL @ $${entryPrice} -> $${currentPrice} = ${outcome} ($${pnl.toFixed(2)})`); } } catch (error) { console.warn(`āŒ Error updating ${trade.id}: ${error.message}`); } } console.log(`\nšŸ“ˆ RESULTS:`); console.log(`āœ… Updated: ${updated} trades`); console.log(`šŸ’° Total P&L impact: $${totalPnl.toFixed(2)}`); console.log(`šŸ“Š These trades will now show proper WIN/LOSS outcomes`); } catch (error) { console.error('āŒ Error updating open positions:', error); } finally { await prisma.$disconnect(); } } // Run the update updateOpenPositions().catch(console.error);