To elevate this script to the level of a proprietary trading firm's Risk Management module, we must transition it from a passive timer to an active Chief Risk Officer (CRO) protocol.
Institutional risk tools do not just track time; they track context, map known volatility events, and surface predefined rules precisely when decision fatigue peaks.
Here is the ultimate iteration. It introduces Weekly PnL Context (tightening the belt if you are already green), visualizes the WMR Fix Danger Zone so you can see the chop you are avoiding, and dynamically alters the HUD to display your specific Rules of Engagement once the cut-off triggers.
Code: Select all
//@version=5
indicator("Enterprise Friday Risk Protocol", overlay=true, max_labels_count=50, max_boxes_count=50)
// ==============================================================================
// 1. DESK CONFIGURATION & PNL CONTEXT
// ==============================================================================
grp_desk = "🏢 Risk Desk Parameters"
weekStatus = input.string("Neutral", title="Current Week Status", options=["Green (Protect)", "Red (Stop Digging)", "Neutral"], group=grp_desk, tooltip="If Green, the system automatically pulls the cut-off forward by 15 mins to protect the week.")
tz = input.string("Europe/London", title="Timezone", group=grp_desk)
grp_asset = "📊 Asset Liquidity Profiles (London Time)"
cutoffHour_FX = input.int(15, title="FX Cut-off", minval=0, maxval=23, group=grp_asset, inline="fx")
cutoffMin_FX = input.int(30, title=":", minval=0, maxval=59, group=grp_asset, inline="fx")
cutoffHour_XAU = input.int(15, title="XAU Cut-off", minval=0, maxval=23, group=grp_asset, inline="xau")
cutoffMin_XAU = input.int(00, title=":", minval=0, maxval=59, group=grp_asset, inline="xau")
warningMins = input.int(30, title="Wind-down Window (Mins)", minval=5, group=grp_asset)
grp_ui = "🖥️ HUD & Visuals"
showDash = input.bool(true, title="Enable Dynamic HUD", group=grp_ui)
showWMR = input.bool(true, title="Highlight 16:00 WMR Fix (Danger Zone)", group=grp_ui)
// ==============================================================================
// 2. DYNAMIC ASSET & TIME PROCESSING
// ==============================================================================
// Auto-detect asset class
isMetals = syminfo.type == "metal" or str.contains(syminfo.tickerid, "XAU") or str.contains(syminfo.tickerid, "GOLD")
baseHour = isMetals ? cutoffHour_XAU : cutoffHour_FX
baseMin = isMetals ? cutoffMin_XAU : cutoffMin_FX
// Apply Weekly PnL Guardrail: If Green, cut-off is pulled forward 15 mins
protectFactor = weekStatus == "Green (Protect)" ? 15 : 0
// Time logic
currDay = dayofweek(time, tz)
isFriday = currDay == dayofweek.friday
currHour = hour(time, tz)
currMin = minute(time, tz)
currTimeInMins = (currHour * 60) + currMin
cutoffTimeInMins = (baseHour * 60) + baseMin - protectFactor
minsToCutoff = cutoffTimeInMins - currTimeInMins
// Define operational states
isWarning = isFriday and (minsToCutoff <= warningMins) and (minsToCutoff > 0)
isCutoff = isFriday and (currTimeInMins >= cutoffTimeInMins)
isWMR = isFriday and (currHour == 16 and currMin <= 15) // WMR Fix Window (16:00 - 16:15)
// Triggers for one-time events
triggerWarning = isWarning and not isWarning[1]
triggerCutoff = isCutoff and not isCutoff[1]
// ==============================================================================
// 3. CHART VISUALS & DANGER ZONES
// ==============================================================================
// Tri-State Background
stateColor = isCutoff ? color.new(#b71c1c, 85) : isWarning ? color.new(#f57c00, 90) : na
bgcolor(stateColor, title="Desk Status Background")
// WMR Fix Volatility Block (Visualizing what you are avoiding)
bgcolor(showWMR and isWMR ? color.new(color.gray, 80) : na, title="WMR Fix Danger Zone")
// Cut-off execution label
if triggerCutoff
labelText = weekStatus == "Green (Protect)" ? "PROFIT LOCKED\nNO NEW RISK" : "DESK CLOSED\nNO NEW RISK"
label.new(bar_index, high, text=labelText, color=color.new(#b71c1c, 0), textcolor=color.white, style=label.style_label_down, yloc=yloc.abovebar, size=size.normal)
// ==============================================================================
// 4. DYNAMIC RULE-BASED HUD
// ==============================================================================
// The HUD expands and changes context based on whether the desk is open or closed.
var table hud = table.new(position.top_right, 2, 7, bgcolor=color.new(#1e222d, 10), border_width=1, border_color=#434651)
if barstate.islast and showDash
// --- Standard Header ---
table.cell(hud, 0, 0, "ASSET PROFILE", text_color=#8a91a5, text_size=size.small, text_halign=text.align_left)
table.cell(hud, 1, 0, isMetals ? "METALS (XAU)" : "FX MAJOR", text_color=color.white, text_size=size.small, text_halign=text.align_right)
table.cell(hud, 0, 1, "DESK CUT-OFF", text_color=#8a91a5, text_size=size.small, text_halign=text.align_left)
// Format cut-off time for display, accounting for the 15-min protection shift
displayHour = math.floor(cutoffTimeInMins / 60)
displayMin = cutoffTimeInMins % 60
table.cell(hud, 1, 1, str.tostring(displayHour, "00") + ":" + str.tostring(displayMin, "00") + " LDN", text_color=color.white, text_size=size.small, text_halign=text.align_right)
// --- Dynamic Status ---
table.cell(hud, 0, 2, "STATUS", text_color=#8a91a5, text_size=size.small, text_halign=text.align_left)
statusText = not isFriday ? "NORMAL" : isCutoff ? "LOCKED" : isWarning ? "WINDING DOWN" : "ACTIVE"
statusColor = not isFriday ? color.gray : isCutoff ? #ff5252 : isWarning ? #ffaa00 : #00e676
table.cell(hud, 1, 2, statusText, text_color=statusColor, text_size=size.small, text_halign=text.align_right)
// --- Active Trading View (Pre Cut-off) ---
if not isCutoff and isFriday
table.cell(hud, 0, 3, "TIME REMAINING", text_color=#8a91a5, text_size=size.small, text_halign=text.align_left)
table.cell(hud, 1, 3, str.tostring(minsToCutoff) + " MIN", text_color=statusColor, text_size=size.small, text_halign=text.align_right)
table.cell(hud, 0, 4, "WEEK CONTEXT", text_color=#8a91a5, text_size=size.small, text_halign=text.align_left)
table.cell(hud, 1, 4, weekStatus, text_color=color.white, text_size=size.small, text_halign=text.align_right)
// Clear unused rows
table.cell(hud, 0, 5, ""), table.cell(hud, 1, 5, "")
table.cell(hud, 0, 6, ""), table.cell(hud, 1, 6, "")
// --- Locked Desk View (Post Cut-off Protocol Display) ---
else if isCutoff
// When cut-off hits, the HUD transforms to display your exact rules.
table.cell(hud, 0, 3, "PROTOCOL", text_color=#ff5252, text_size=size.small, text_halign=text.align_left)
table.cell(hud, 1, 3, "HARD BLACKOUT", text_color=#ff5252, text_size=size.small, text_halign=text.align_right)
table.cell(hud, 0, 4, "✅ ALLOWED", text_color=#00e676, text_size=size.small, text_halign=text.align_left)
table.cell(hud, 1, 4, "• Manage Open to Exit\n• Log the Day\n• Swap Notes", text_color=color.white, text_size=size.small, text_halign=text.align_right)
table.cell(hud, 0, 5, "❌ DENIED", text_color=#ff5252, text_size=size.small, text_halign=text.align_left)
table.cell(hud, 1, 5, "• Revenge Size\n• Asia Gap Metals\n• +30 Min Extension", text_color=color.white, text_size=size.small, text_halign=text.align_right)
table.cell(hud, 0, 6, "RATIONALE", text_color=#8a91a5, text_size=size.small, text_halign=text.align_left)
table.cell(hud, 1, 6, weekStatus == "Green (Protect)" ? "Protect the Week." : "Stop Digging.", text_color=color.white, text_size=size.small, text_halign=text.align_right)