Files
trading_bot_v4/app/api/trading/positions/route.ts
mindesbunister 2405bff68a feat: Complete Trading Bot v4 with Drift Protocol integration
Features:
- Autonomous trading system with Drift Protocol on Solana
- Real-time position monitoring with Pyth price feeds
- Dynamic stop-loss and take-profit management
- n8n workflow integration for TradingView signals
- Beautiful web UI for settings management
- REST API for trade execution and monitoring

- Next.js 15 with standalone output mode
- TypeScript with strict typing
- Docker containerization with multi-stage builds
- PostgreSQL database for trade history
- Singleton pattern for Drift client connection pooling
- BN.js for BigNumber handling (Drift SDK requirement)

- Configurable stop-loss and take-profit levels
- Breakeven trigger and profit locking
- Daily loss limits and trade cooldowns
- Slippage tolerance controls
- DRY_RUN mode for safe testing

- Real-time risk calculator
- Interactive sliders for all parameters
- Live preview of trade outcomes
- Position sizing and leverage controls
- Beautiful gradient design with Tailwind CSS

- POST /api/trading/execute - Execute trades
- POST /api/trading/close - Close positions
- GET /api/trading/positions - Monitor active trades
- GET /api/trading/check-risk - Validate trade signals
- GET /api/settings - View configuration
- POST /api/settings - Update configuration

- Fixed Borsh serialization errors (simplified order params)
- Resolved RPC rate limiting with singleton pattern
- Fixed BigInt vs BN type mismatches
- Corrected order execution flow
- Improved position state management

- Complete setup guides
- Docker deployment instructions
- n8n workflow configuration
- API reference documentation
- Risk management guidelines

- Runs on port 3001 (external), 3000 (internal)
- Uses Helius RPC for optimal performance
- Production-ready with error handling
- Health monitoring and logging
2025-10-24 14:24:36 +02:00

134 lines
3.5 KiB
TypeScript

/**
* Get Active Positions API Endpoint
*
* Returns all currently monitored positions
* GET /api/trading/positions
*/
import { NextRequest, NextResponse } from 'next/server'
import { getPositionManager } from '@/lib/trading/position-manager'
export interface PositionsResponse {
success: boolean
monitoring: {
isActive: boolean
tradeCount: number
symbols: string[]
}
positions: Array<{
id: string
symbol: string
direction: 'long' | 'short'
entryPrice: number
currentPrice: number
entryTime: string
positionSize: number
currentSize: number
leverage: number
stopLoss: number
takeProfit1: number
takeProfit2: number
tp1Hit: boolean
slMovedToBreakeven: boolean
realizedPnL: number
unrealizedPnL: number
peakPnL: number
profitPercent: number
accountPnL: number
priceChecks: number
ageMinutes: number
}>
}
export async function GET(request: NextRequest): Promise<NextResponse<PositionsResponse>> {
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,
monitoring: { isActive: false, tradeCount: 0, symbols: [] },
positions: [],
} as any,
{ status: 401 }
)
}
const positionManager = getPositionManager()
const status = positionManager.getStatus()
const trades = positionManager.getActiveTrades()
const positions = trades.map(trade => {
const profitPercent = calculateProfitPercent(
trade.entryPrice,
trade.lastPrice,
trade.direction
)
const accountPnL = profitPercent * trade.leverage
const ageMinutes = Math.floor((Date.now() - trade.entryTime) / 60000)
return {
id: trade.id,
symbol: trade.symbol,
direction: trade.direction,
entryPrice: trade.entryPrice,
currentPrice: trade.lastPrice,
entryTime: new Date(trade.entryTime).toISOString(),
positionSize: trade.positionSize,
currentSize: trade.currentSize,
leverage: trade.leverage,
stopLoss: trade.stopLossPrice,
takeProfit1: trade.tp1Price,
takeProfit2: trade.tp2Price,
tp1Hit: trade.tp1Hit,
slMovedToBreakeven: trade.slMovedToBreakeven,
realizedPnL: trade.realizedPnL,
unrealizedPnL: trade.unrealizedPnL,
peakPnL: trade.peakPnL,
profitPercent: profitPercent,
accountPnL: accountPnL,
priceChecks: trade.priceCheckCount,
ageMinutes,
}
})
return NextResponse.json({
success: true,
monitoring: {
isActive: status.isMonitoring,
tradeCount: status.activeTradesCount,
symbols: status.symbols,
},
positions,
})
} catch (error) {
console.error('❌ Error fetching positions:', error)
return NextResponse.json(
{
success: false,
monitoring: { isActive: false, tradeCount: 0, symbols: [] },
positions: [],
} as any,
{ status: 500 }
)
}
}
function calculateProfitPercent(
entryPrice: number,
currentPrice: number,
direction: 'long' | 'short'
): number {
if (direction === 'long') {
return ((currentPrice - entryPrice) / entryPrice) * 100
} else {
return ((entryPrice - currentPrice) / entryPrice) * 100
}
}