diff --git a/app/api/trading/remove-position/route.ts b/app/api/trading/remove-position/route.ts new file mode 100644 index 0000000..61bd591 --- /dev/null +++ b/app/api/trading/remove-position/route.ts @@ -0,0 +1,115 @@ +/** + * Remove Position from Tracking + * + * Manually removes a position from Position Manager tracking + * POST /api/trading/remove-position + */ + +import { NextRequest, NextResponse } from 'next/server' +import { getInitializedPositionManager } from '@/lib/trading/position-manager' +import { updateTradeExit } from '@/lib/database/trades' + +interface RemovePositionRequest { + tradeId: string + reason?: string +} + +interface RemovePositionResponse { + success: boolean + message: string + tradeId?: string +} + +export async function POST(request: NextRequest): Promise> { + try { + // Verify authorization + const authHeader = request.headers.get('authorization') + const expectedAuth = `Bearer ${process.env.API_SECRET_KEY}` + + if (!authHeader || authHeader !== expectedAuth) { + return NextResponse.json( + { + success: false, + message: 'Unauthorized', + }, + { status: 401 } + ) + } + + const body: RemovePositionRequest = await request.json() + + console.log('🗑️ Removing position from tracking:', body) + + if (!body.tradeId) { + return NextResponse.json( + { + success: false, + message: 'tradeId is required', + }, + { status: 400 } + ) + } + + // Get Position Manager + const positionManager = await getInitializedPositionManager() + + // Check if position exists + const activeTrades = positionManager.getActiveTrades() + const trade = activeTrades.find(t => t.id === body.tradeId) + + if (!trade) { + return NextResponse.json( + { + success: false, + message: `Position ${body.tradeId} not found in tracking`, + }, + { status: 404 } + ) + } + + console.log(`📊 Found position: ${trade.symbol} ${trade.direction} at $${trade.entryPrice}`) + + // Remove from Position Manager + positionManager.removeTrade(body.tradeId) + + console.log(`✅ Removed ${body.tradeId} from Position Manager`) + + // Update database to mark as closed (manually) + try { + const exitTime = new Date() + const holdTime = Math.floor((exitTime.getTime() - new Date(trade.entryTime).getTime()) / 1000) + + await updateTradeExit({ + positionId: trade.positionId || 'manual-removal', + exitPrice: trade.lastPrice || trade.entryPrice, + exitReason: 'manual', + realizedPnL: trade.unrealizedPnL, + exitOrderTx: 'manual-removal', + holdTimeSeconds: holdTime, + maxDrawdown: trade.peakPnL < 0 ? trade.peakPnL : undefined, + maxGain: trade.peakPnL > 0 ? trade.peakPnL : undefined, + }) + console.log('💾 Updated database: trade marked as closed') + } catch (dbError) { + console.error('❌ Failed to update database:', dbError) + // Don't fail the removal if database update fails + } + + return NextResponse.json({ + success: true, + message: `Position removed from tracking: ${trade.symbol} ${trade.direction}`, + tradeId: body.tradeId, + }) + + } catch (error) { + console.error('❌ Remove position error:', error) + + return NextResponse.json( + { + success: false, + message: error instanceof Error ? error.message : 'Unknown error', + }, + { status: 500 } + ) + } +}