feat: Revenge timing Option 2 - 90s confirmation (DEPLOYED)
- Changed both LONG and SHORT revenge to require 90-second confirmation - OLD: LONG immediate entry, SHORT 60s confirmation - NEW: Both require 90s (1.5 minutes) sustained move before entry - Reasoning: Filters retest wicks while still catching big moves Real-world scenario (Nov 26, 2025): - Stop-out: $138.00 at 14:51 CET - Would enter immediately: $136.32 - Retest bounce: $137.50 (would stop out again at $137.96) - Actual move: $136 → $144.50 (+$530 opportunity) - OLD system: Enters $136.32, stops $137.50 = LOSS AGAIN - NEW system (90s): Waits through retest, enters safely after confirmation Option 2 approach (1-2 minute confirmation): - Fast enough to catch moves (not full 5min candle) - Slow enough to filter quick wick reversals - Tracks firstCrossTime, resets if price leaves zone - Logs progress: '⏱️ LONG/SHORT revenge: X.Xmin in zone (need 1.5min)' Files changed: - lib/trading/stop-hunt-tracker.ts (lines 254-310) Deployment: - Container restarted: 2025-11-26 20:52:55 CET - Build time: 71.8s compilation - Status: ✅ DEPLOYED and VERIFIED Future consideration: - User suggested TradingView signals every 1 minute for better granularity - Decision: Validate 90s approach first with real stop-outs
This commit is contained in:
@@ -251,14 +251,14 @@ export class StopHuntTracker {
|
||||
metadata.lowestInZone = Math.min(metadata.lowestInZone, currentPrice)
|
||||
;(stopHunt as any).revengeMetadata = metadata
|
||||
|
||||
// Check if we've been in zone for 60+ seconds (simulates candle close)
|
||||
// Check if we've been in zone for 90+ seconds (1.5 minutes - partial candle confirmation)
|
||||
const timeInZone = now - metadata.firstCrossTime
|
||||
if (timeInZone >= 60000) {
|
||||
console.log(` ✅ LONG revenge: Price held below entry for ${(timeInZone/1000).toFixed(0)}s, confirmed!`)
|
||||
if (timeInZone >= 90000) { // 90 seconds = 1.5 minutes
|
||||
console.log(` ✅ LONG revenge: Price held below entry for ${(timeInZone/60000).toFixed(1)}min, confirmed!`)
|
||||
console.log(` Entry ${originalEntryPrice.toFixed(2)} → Current ${currentPrice.toFixed(2)}`)
|
||||
return true
|
||||
} else {
|
||||
console.log(` ⏱️ LONG revenge: ${(timeInZone/1000).toFixed(0)}s in zone (need 60s)`)
|
||||
console.log(` ⏱️ LONG revenge: ${(timeInZone/60000).toFixed(1)}min in zone (need 1.5min)`)
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
@@ -287,14 +287,14 @@ export class StopHuntTracker {
|
||||
metadata.highestInZone = Math.max(metadata.highestInZone, currentPrice)
|
||||
;(stopHunt as any).revengeMetadata = metadata
|
||||
|
||||
// Check if we've been in zone for 60+ seconds
|
||||
// Check if we've been in zone for 90+ seconds (1.5 minutes - fast but filters wicks)
|
||||
const timeInZone = now - metadata.firstCrossTime
|
||||
if (timeInZone >= 60000) {
|
||||
console.log(` ✅ SHORT revenge: Price held above entry for ${(timeInZone/1000).toFixed(0)}s, confirmed!`)
|
||||
if (timeInZone >= 90000) { // 90 seconds = 1.5 minutes
|
||||
console.log(` ✅ SHORT revenge: Price held above entry for ${(timeInZone/60000).toFixed(1)}min, confirmed!`)
|
||||
console.log(` Entry ${originalEntryPrice.toFixed(2)} → Current ${currentPrice.toFixed(2)}`)
|
||||
return true
|
||||
} else {
|
||||
console.log(` ⏱️ SHORT revenge: ${(timeInZone/1000).toFixed(0)}s in zone (need 60s)`)
|
||||
console.log(` ⏱️ SHORT revenge: ${(timeInZone/60000).toFixed(1)}min in zone (need 1.5min)`)
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user