Code: Select all
//@version=5
strategy("Pro Anti-FOMO Execution Engine", overlay=true, calc_on_every_tick=true, max_labels_count=500, max_lines_count=500, max_boxes_count=500)
// =========================================================================
// 1. INPUTS & PARAMETERS
// =========================================================================
var grp_fomo = "FOMO Mechanics"
var grp_session= "Session Boundaries"
var grp_risk = "Risk & Structure"
// FOMO Rules
maxChaseTicks = input.int(50, title="Max Chase Allowance (Ticks)", group=grp_fomo)
cooldownBars = input.int(1, title="Cooldown Wait (Bars)", group=grp_fomo)
// Session (e.g., London / Live Mornings)
sessRange = input.session("0800-1130", title="Trading Session", group=grp_session)
sessTz = input.string("Europe/London", title="Timezone", group=grp_session)
// Mock Setup Parameters (Replace with your own logic)
slTicks = input.int(30, title="Stop Loss (Ticks)", group=grp_risk)
tpTicks = input.int(60, title="Take Profit (Ticks)", group=grp_risk)
// =========================================================================
// 2. CONSTANTS & STATE TRACKING
// =========================================================================
tickSize = syminfo.mintick
chaseDist = maxChaseTicks * tickSize
slDist = slTicks * tickSize
tpDist = tpTicks * tickSize
// Tracking State
var int tradeState = 0 // 0 = Flat, 1 = Pending Long, -1 = Pending Short, 2 = In Long, -2 = In Short
var float entryLevel = na
var float slLevel = na
var float tpLevel = na
var int cooldownEnd = 0
var box fomoBox = na
// Psychological Scoreboard Stats
var int stats_missOk = 0
var int stats_filled = 0
// Session State
inSession = not na(time(timeframe.period, sessRange, sessTz))
sessionEnd = inSession[1] and not inSession
// =========================================================================
// 3. MOCK SIGNAL GENERATION (Replace with your actual edge)
// =========================================================================
// *Example: RSI overbought/oversold extreme pullbacks*
rsi = ta.rsi(close, 14)
signalLong = ta.crossunder(rsi, 30)
signalShort = ta.crossover(rsi, 70)
// =========================================================================
// 4. ORDER ARMING (The Pre-Commitment)
// =========================================================================
bool canTrade = inSession and tradeState == 0 and bar_index > cooldownEnd
if canTrade and signalLong
entryLevel := low - (10 * tickSize) // Limit placed below current low
slLevel := entryLevel - slDist
tpLevel := entryLevel + tpDist
tradeState := 1
strategy.entry("Long", strategy.long, limit=entryLevel)
// Draw FOMO Invalidation Box (Visual Boundary)
fomoBox := box.new(left=bar_index, top=entryLevel + chaseDist, right=bar_index + 10, bottom=entryLevel,
border_color=color.new(color.blue, 50), bgcolor=color.new(color.blue, 90), text="VALID ENTRY ZONE")
if canTrade and signalShort
entryLevel := high + (10 * tickSize) // Limit placed above current high
slLevel := entryLevel + slDist
tpLevel := entryLevel - tpDist
tradeState := -1
strategy.entry("Short", strategy.short, limit=entryLevel)
// Draw FOMO Invalidation Box
fomoBox := box.new(left=bar_index, top=entryLevel, right=bar_index + 10, bottom=entryLevel - chaseDist,
border_color=color.new(color.red, 50), bgcolor=color.new(color.red, 90), text="VALID ENTRY ZONE")
// =========================================================================
// 5. FOMO FRICTION & ORDER MANAGEMENT
// =========================================================================
if tradeState == 1 or tradeState == -1 // If order is pending
// Extend box to current bar to keep UI clean
box.set_right(fomoBox, bar_index + 1)
// Check if Filled
if strategy.position_size != 0
tradeState := strategy.position_size > 0 ? 2 : -2
stats_filled += 1
box.delete(fomoBox) // Clear the zone once filled
// Place SL & TP
strategy.exit("Exit", from_entry=strategy.position_size > 0 ? "Long" : "Short", stop=slLevel, limit=tpLevel)
// Check Long FOMO Cancel Condition
else if tradeState == 1 and (high > (entryLevel + chaseDist) or sessionEnd)
strategy.cancel("Long")
tradeState := 0
cooldownEnd := bar_index + cooldownBars
stats_missOk += 1
box.set_bgcolor(fomoBox, color.new(color.gray, 80))
box.set_text(fomoBox, "miss_ok\n(Canceled)")
alert("FOMO Saved: Long Cancelled", alert.freq_once_per_bar_close)
// Check Short FOMO Cancel Condition
else if tradeState == -1 and (low < (entryLevel - chaseDist) or sessionEnd)
strategy.cancel("Short")
tradeState := 0
cooldownEnd := bar_index + cooldownBars
stats_missOk += 1
box.set_bgcolor(fomoBox, color.new(color.gray, 80))
box.set_text(fomoBox, "miss_ok\n(Canceled)")
alert("FOMO Saved: Short Cancelled", alert.freq_once_per_bar_close)
// Reset state when flat
if strategy.position_size == 0 and (tradeState == 2 or tradeState == -2)
tradeState := 0
// =========================================================================
// 6. PSYCHOLOGICAL DASHBOARD (The Reward Mechanism)
// =========================================================================
var table statsTable = table.new(position.top_right, 2, 4, border_width=1, border_color=color.gray, frame_color=color.gray, frame_width=1)
if barstate.islast
// Header
table.cell(statsTable, 0, 0, "Execution State", bgcolor=color.new(color.gray, 80), text_color=color.white)
table.cell(statsTable, 1, 0, "Stats", bgcolor=color.new(color.gray, 80), text_color=color.white)
// State Info
string currentState = tradeState == 0 ? (inSession ? "SEARCHING" : "OUT OF SESSION") : (tradeState == 1 or tradeState == -1) ? "ARMED (Pending)" : "IN TRADE"
color stateColor = tradeState == 0 ? color.gray : (tradeState == 1 or tradeState == -1) ? color.orange : color.green
if bar_index <= cooldownEnd
currentState := "COOLDOWN (Locked)"
stateColor := color.red
table.cell(statsTable, 0, 1, currentState, text_color=stateColor, text_halign=text.align_left)
// Tallies
table.cell(statsTable, 1, 1, "", text_color=color.white) // Blank spacer
table.cell(statsTable, 0, 2, "Trades Executed", text_color=color.white, text_halign=text.align_left)
table.cell(statsTable, 1, 2, str.tostring(stats_filled), text_color=color.green, text_halign=text.align_right)
table.cell(statsTable, 0, 3, "FOMO Saves (miss_ok)", text_color=color.white, text_halign=text.align_left)
table.cell(statsTable, 1, 3, str.tostring(stats_missOk), text_color=color.orange, text_halign=text.align_right)