Enhancement #4: Failed Revenge Tracking - Added 3 database fields: revengeOutcome, revengePnL, revengeFailedReason - Added updateRevengeOutcome() method in stop-hunt-tracker.ts - Position Manager hooks revenge trade closes, records outcome - Enables data-driven analysis of revenge success rate Enhancement #10: Metadata Persistence - Added 4 database fields: firstCrossTime, lowestInZone, highestInZone, zoneResetCount - Migrated 90-second zone tracking from in-memory to database - Rewrote shouldExecuteRevenge() with database persistence - Container restarts now preserve exact zone tracking state Technical Details: - Prisma schema updated with 7 new StopHunt fields - Added signalSource field to ActiveTrade interface - All zone metadata persisted in real-time to database - Build verified successful (no TypeScript errors) Files Changed: - prisma/schema.prisma (StopHunt model + index) - lib/trading/stop-hunt-tracker.ts (DB persistence + outcome tracking) - lib/trading/position-manager.ts (revenge hook + interface) - docs/REVENGE_ENHANCEMENTS_EXPLAINED.md (comprehensive guide) Pending User Decision: - Enhancement #1: ADX confirmation (3 options explained in docs) - Enhancement #6: SL distance validation (2× ATR recommended) Status: Ready for deployment after Prisma migration Date: Nov 27, 2025
This commit is contained in:
@@ -26,6 +26,7 @@ export interface ActiveTrade {
|
||||
atrAtEntry?: number // ATR value at entry for ATR-based trailing stop
|
||||
adxAtEntry?: number // ADX value at entry for trend strength multiplier
|
||||
signalQualityScore?: number // Quality score for stop hunt tracking
|
||||
signalSource?: string // Trade source: 'tradingview', 'manual', 'stop_hunt_revenge'
|
||||
|
||||
// Targets
|
||||
stopLossPrice: number
|
||||
@@ -1551,6 +1552,26 @@ export class PositionManager {
|
||||
maxAdversePrice: trade.maxAdversePrice,
|
||||
})
|
||||
console.log('💾 Trade saved to database')
|
||||
|
||||
// 🔥 REVENGE OUTCOME TRACKING (Enhancement #4 - Nov 27, 2025)
|
||||
// If this was a revenge trade, record the outcome in StopHunt table
|
||||
if (trade.signalSource === 'stop_hunt_revenge') {
|
||||
try {
|
||||
const { getStopHuntTracker } = await import('./stop-hunt-tracker')
|
||||
const tracker = getStopHuntTracker()
|
||||
|
||||
await tracker.updateRevengeOutcome({
|
||||
revengeTradeId: trade.id,
|
||||
outcome: reason as string,
|
||||
pnl: trade.realizedPnL,
|
||||
failedReason: reason === 'SL' ? 'stopped_again' : undefined
|
||||
})
|
||||
console.log(`🔥 Revenge outcome recorded: ${reason} (P&L: $${trade.realizedPnL.toFixed(2)})`)
|
||||
} catch (revengeError) {
|
||||
console.error('❌ Failed to record revenge outcome:', revengeError)
|
||||
// Don't fail trade closure if revenge tracking fails
|
||||
}
|
||||
}
|
||||
} catch (dbError) {
|
||||
console.error('❌ Failed to save trade exit to database:', dbError)
|
||||
// Don't fail the close if database fails
|
||||
|
||||
Reference in New Issue
Block a user