-- Fix Zero P&L Trades -- This script recalculates P&L for trades that were incorrectly recorded as $0.00 -- Created: 2025-11-03 -- Backup: backup_before_pnl_fix_20251103_091248.sql -- First, let's see what we're fixing SELECT id, symbol, direction, ROUND("entryPrice"::numeric, 2) as entry, ROUND("exitPrice"::numeric, 2) as exit, "positionSizeUSD", leverage, "realizedPnL" as current_pnl, "exitReason" FROM "Trade" WHERE "realizedPnL" = 0 AND "exitReason" IS NOT NULL AND "exitPrice" IS NOT NULL AND "exitOrderTx" IN ('ON_CHAIN_ORDER', 'UNKNOWN_CLOSURE') ORDER BY "entryTime" DESC; -- Calculate and update P&L for zero-P&L trades -- Formula: realizedPnL = (positionSizeUSD * profitPercent * leverage) / 100 -- profitPercent = ((exitPrice - entryPrice) / entryPrice) * 100 * (direction multiplier) UPDATE "Trade" SET "realizedPnL" = CASE WHEN direction = 'long' THEN -- Long: profit when exit > entry ("positionSizeUSD" * ((("exitPrice" - "entryPrice") / "entryPrice") * 100) * leverage) / 100 WHEN direction = 'short' THEN -- Short: profit when exit < entry ("positionSizeUSD" * ((("entryPrice" - "exitPrice") / "entryPrice") * 100) * leverage) / 100 ELSE 0 END, "realizedPnLPercent" = CASE WHEN direction = 'long' THEN ((("exitPrice" - "entryPrice") / "entryPrice") * 100) * leverage WHEN direction = 'short' THEN ((("entryPrice" - "exitPrice") / "entryPrice") * 100) * leverage ELSE 0 END, "updatedAt" = NOW() WHERE "realizedPnL" = 0 AND "exitReason" IS NOT NULL AND "exitPrice" IS NOT NULL AND "exitOrderTx" IN ('ON_CHAIN_ORDER', 'UNKNOWN_CLOSURE'); -- Show the results after fix SELECT id, symbol, direction, ROUND("entryPrice"::numeric, 2) as entry, ROUND("exitPrice"::numeric, 2) as exit, ROUND("positionSizeUSD"::numeric, 2) as size, leverage, ROUND("realizedPnL"::numeric, 2) as fixed_pnl, ROUND("realizedPnLPercent"::numeric, 2) as pnl_percent, "exitReason" FROM "Trade" WHERE "exitOrderTx" IN ('ON_CHAIN_ORDER', 'UNKNOWN_CLOSURE') AND "exitReason" IS NOT NULL ORDER BY "entryTime" DESC; -- Show new total P&L SELECT COUNT(*) as total_trades, SUM(CASE WHEN "realizedPnL" > 0 THEN 1 ELSE 0 END) as wins, SUM(CASE WHEN "realizedPnL" <= 0 THEN 1 ELSE 0 END) as losses, ROUND(SUM("realizedPnL")::numeric, 2) as total_pnl, ROUND(AVG(CASE WHEN "realizedPnL" > 0 THEN "realizedPnL" END)::numeric, 2) as avg_win, ROUND(AVG(CASE WHEN "realizedPnL" <= 0 THEN "realizedPnL" END)::numeric, 2) as avg_loss FROM "Trade" WHERE "entryTime" >= NOW() - INTERVAL '7 days' AND "exitReason" IS NOT NULL;