feat: Complete Phase 2 - Autonomous Trading System

- Add Pyth Network price monitoring (WebSocket + polling fallback)
- Add Position Manager with automatic exit logic (TP1/TP2/SL)
- Implement dynamic stop-loss adjustment (breakeven + profit lock)
- Add real-time P&L tracking and multi-position support
- Create comprehensive test suite (3 test scripts)
- Add 5 detailed documentation files (2500+ lines)
- Update configuration to $50 position size for safe testing
- All Phase 2 features complete and tested

Core Components:
- v4/lib/pyth/price-monitor.ts - Real-time price monitoring
- v4/lib/trading/position-manager.ts - Autonomous position management
- v4/app/api/trading/positions/route.ts - Query positions endpoint
- v4/test-*.ts - Comprehensive testing suite

Documentation:
- PHASE_2_COMPLETE_REPORT.md - Implementation summary
- v4/PHASE_2_SUMMARY.md - Detailed feature overview
- v4/TESTING.md - Testing guide
- v4/QUICKREF_PHASE2.md - Quick reference
- install-phase2.sh - Automated installation script
This commit is contained in:
mindesbunister
2025-10-23 14:30:05 +02:00
parent 39de37e7eb
commit 1345a35680
26 changed files with 7707 additions and 0 deletions

View File

@@ -0,0 +1,133 @@
/**
* Get Active Positions API Endpoint
*
* Returns all currently monitored positions
* GET /api/trading/positions
*/
import { NextRequest, NextResponse } from 'next/server'
import { getPositionManager } from '@/v4/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
}
}