quantum-algonexta.pine · 496 lines · 26.9 KB
Not yet verified on the native platform — test it before relying on it.
The original uploaded source.
// ============================================================================
// © algonexta
// This script is for education and research; it does not guarantee results.
// Verify this source in TradingView before use.
// ============================================================================
//@version=6
indicator("AlgoNexta Quantum MTF V1 [Non-Repainting]", "ANQ MTF V1", overlay = true, max_labels_count = 500)
// Research indicator. It does not claim that markets obey quantum physics.
// Designed exclusively for a standard 5-minute chart.
// ───────────────────────────── Inputs
string G_LATTICE = "Quantum Lattice"
float fastK = input.float(2.0, "Fast K", 0.5, 10.0, 0.1, group = G_LATTICE)
float coreK = input.float(2.5, "Core K", 0.5, 10.0, 0.1, group = G_LATTICE)
float macroK = input.float(3.0, "Macro K", 0.5, 10.0, 0.1, group = G_LATTICE)
int h1SigmaPeriod = input.int(24, "H1 Sigma Period", 5, 500, group = G_LATTICE)
int m15SigmaPeriod = input.int(48, "M15 Sigma Period", 5, 1000, group = G_LATTICE)
int m5SigmaPeriod = input.int(72, "M5 Sigma Period", 5, 2000, group = G_LATTICE)
float rebaseRatio = input.float(1.50, "Volatility Rebase Ratio", 1.05, 5.0, 0.05, group = G_LATTICE)
int maxMacroIndex = input.int(6, "Max Macro Orbital", 1, 100, group = G_LATTICE)
int maxEpochBars = input.int(0, "Max Epoch Bars (0 = off)", 0, 100000, group = G_LATTICE)
string G_REGIME = "H1 Regime"
int pathLength = input.int(6, "State Path Length", 3, 50, group = G_REGIME)
int minH1Persistence = input.int(2, "Min H1 Persistence", 1, 100, group = G_REGIME)
int reflectionAlternations = input.int(2, "Reflection Alternations", 1, 20, group = G_REGIME)
string G_EVENT = "M15 Events"
float approachFraction = input.float(0.20, "Approach Fraction", 0.01, 0.49, 0.01, group = G_EVENT)
float jumpBufferFraction = input.float(0.10, "Jump Buffer Fraction", 0.0, 1.0, 0.01, group = G_EVENT)
int jumpConfirmBars = input.int(1, "Jump Confirm Bars", 1, 10, group = G_EVENT)
float reflectionDepthFraction = input.float(0.25, "Reflection Depth Fraction", 0.01, 1.0, 0.01, group = G_EVENT)
int reflectionMaxBars = input.int(4, "Reflection Max Bars", 1, 50, group = G_EVENT)
int maxEventBars = input.int(8, "Max M15 Event Bars", 1, 100, group = G_EVENT)
int eventCooldownBars = input.int(2, "Event Cooldown (M15 bars)", 0, 20, group = G_EVENT, tooltip = "Minimum closed M15 bars after a final event before another event is allowed.")
bool oneEventPerBoundary = input.bool(true, "One Event Per Boundary / Epoch", group = G_EVENT, tooltip = "Prevents repeated counting of the same directional boundary interaction during one frozen M15 epoch.")
string G_EXEC = "M5 Execution"
float retestToleranceFraction = input.float(0.15, "Retest Tolerance Fraction", 0.01, 1.0, 0.01, group = G_EXEC)
int executionTimeoutBars = input.int(6, "Execution Timeout Bars", 1, 100, group = G_EXEC)
float maxEntryBarSigma = input.float(2.0, "Max Entry Bar Sigma", 0.1, 20.0, 0.1, group = G_EXEC)
string G_VIEW = "Display"
bool showFast = input.bool(false, "Show Fast Boundaries", group = G_VIEW)
bool showCore = input.bool(true, "Show Core Boundaries", group = G_VIEW)
bool showMacro = input.bool(false, "Show Macro Boundaries", group = G_VIEW)
bool showApproach = input.bool(false, "Show Approach Markers", group = G_VIEW)
bool showEvents = input.bool(true, "Show M15 Event Labels", group = G_VIEW)
bool showEntries = input.bool(true, "Show M5 Entry Signals", group = G_VIEW)
bool showDashboard = input.bool(true, "Show Dashboard", group = G_VIEW)
string signalDisplay = input.string("Events + Entries", "Signal Density", options = ["Entries only", "Events + Entries", "All"], group = G_VIEW)
if timeframe.in_seconds() != timeframe.in_seconds("5")
runtime.error("AlgoNexta Quantum MTF V1 must run on a standard M5 chart.")
// Confirmed HTF values: every higher-timeframe series is read with [1] (the last
// closed HTF bar) and lookahead_off, so values never change after they appear.
[h1Time, h1Close, h1Sigma] = request.security(syminfo.tickerid, "60", [time[1], close[1], ta.stdev(ta.change(close), h1SigmaPeriod)[1]], lookahead = barmerge.lookahead_off)
[m15Time, m15Open, m15High, m15Low, m15Close, m15Volume, m15Sigma] = request.security(syminfo.tickerid, "15", [time[1], open[1], high[1], low[1], close[1], volume[1], ta.stdev(ta.change(close), m15SigmaPeriod)[1]], lookahead = barmerge.lookahead_off)
bool newH1 = not na(h1Time) and ta.change(h1Time) != 0
bool newM15 = not na(m15Time) and ta.change(m15Time) != 0
float m5Sigma = ta.stdev(ta.change(close), m5SigmaPeriod)
bool warm = not na(h1Sigma) and h1Sigma > 0 and not na(m15Sigma) and m15Sigma > 0 and not na(m5Sigma) and m5Sigma > 0
f_state(float price, float anchor, float delta) =>
int(math.floor((price - anchor) / delta))
f_alternations(array<int> path) =>
int count = 0
int lastDir = 0
int size = array.size(path)
if size > 1
for i = 1 to size - 1
int d = int(math.sign(array.get(path, i) - array.get(path, i - 1)))
if lastDir != 0 and d != 0 and d != lastDir
count += 1
if d != 0
lastDir := d
count
f_net(array<int> path) =>
array.size(path) > 1 ? array.get(path, array.size(path) - 1) - array.get(path, 0) : 0
f_push_state(array<int> path, int value, int maxSize) =>
if array.size(path) == 0 or array.get(path, array.size(path) - 1) != value
array.push(path, value)
if array.size(path) > maxSize
array.shift(path)
f_push_key(array<string> keys, string value, int maxSize) =>
array.push(keys, value)
if array.size(keys) > maxSize
array.shift(keys)
f_regime_name(int regime) =>
regime == 1 ? "Bullish" : regime == -1 ? "Bearish" : regime == 2 ? "Reflection" : regime == 0 ? "Neutral" : "Uncertain"
f_align_name(int alignment) =>
alignment == 1 ? "Aligned" : alignment == -1 ? "Opposed" : "Neutral"
// ───────────────────────────── H1 epoch and regime
var int h1EpochId = 0
var float h1Anchor = na
var float h1EpochSigma = na
var float h1CoreDelta = na
var float h1MacroDelta = na
var int h1EpochAge = 0
var int h1CoreState = 0
var int h1MacroState = 0
var int h1CorePersistence = 0
var int h1LastCoreDirection = 0
var array<int> h1CorePath = array.new_int()
var array<int> h1MacroPath = array.new_int()
var int h1Regime = 99
if newH1 and not na(h1Sigma) and h1Sigma > 0
bool h1Rebase = na(h1Anchor)
if not h1Rebase
float sigmaRatio = math.max(h1Sigma / h1EpochSigma, h1EpochSigma / h1Sigma)
int liveMacroState = f_state(h1Close, h1Anchor, h1MacroDelta)
h1Rebase := sigmaRatio >= rebaseRatio or math.abs(liveMacroState) > maxMacroIndex or (maxEpochBars > 0 and h1EpochAge >= maxEpochBars)
if h1Rebase
h1EpochId += 1
h1Anchor := h1Close
h1EpochSigma := h1Sigma
h1CoreDelta := coreK * h1Sigma
h1MacroDelta := macroK * h1Sigma
h1EpochAge := 0
else
h1EpochAge += 1
int nextCore = f_state(h1Close, h1Anchor, h1CoreDelta)
int nextMacro = f_state(h1Close, h1Anchor, h1MacroDelta)
if array.size(h1CorePath) == 0
h1CorePersistence := 1
else if nextCore == h1CoreState
h1CorePersistence += 1
else
h1LastCoreDirection := int(math.sign(nextCore - h1CoreState))
h1CorePersistence := 1
h1CoreState := nextCore
h1MacroState := nextMacro
f_push_state(h1CorePath, nextCore, pathLength)
f_push_state(h1MacroPath, nextMacro, pathLength)
int coreNet = f_net(h1CorePath)
int macroNet = f_net(h1MacroPath)
int alternations = f_alternations(h1CorePath)
h1Regime := coreNet >= 1 and h1LastCoreDirection >= 0 and macroNet >= 0 and h1CorePersistence >= minH1Persistence ? 1 : coreNet <= -1 and h1LastCoreDirection <= 0 and macroNet <= 0 and h1CorePersistence >= minH1Persistence ? -1 : math.abs(coreNet) == 0 and alternations >= reflectionAlternations ? 2 : 0
// ───────────────────────────── M15 epoch
var int m15EpochId = 0
var float m15Anchor = na
var float m15EpochSigma = na
var float m15FastDelta = na
var float m15CoreDelta = na
var float m15MacroDelta = na
var int m15EpochAge = 0
var int m15FastState = 0
var int m15CoreState = 0
var int m15MacroState = 0
var int m15CorePersistence = 0
var int m15LastFastState = 0
var int m15LastMacroDirection = 0
var array<int> m15CorePath = array.new_int()
// Active event fields. Decision data is copied and frozen at interaction.
var bool eventActive = false
var int eventSequence = 0
var int eventDirection = 0
var int eventOriginState = 0
var int eventTargetState = 0
var float eventBoundary = na
var float eventNextBoundary = na
var float eventPreviousBoundary = na
var float eventCoreDelta = na
var int eventBars = 0
var int eventJumpCount = 0
var bool eventProvisional = false
var bool eventNextTouched = false
var int eventAlignment = 0
var int eventH1Regime = 99
// Outcome codes: 1 QJ_UP, 2 QJ_DOWN, 3 QR_UPPER, 4 QR_LOWER,
// 5 QF_UP, 6 QF_DOWN, 7 EXPIRED.
var int lastOutcome = 0
var int lastOutcomeTime = na
var int eventCooldown = 0
var array<string> processedBoundaryKeys = array.new_string()
bool approachSignal = false
bool eventFinalized = false
if newM15 and not na(m15Sigma) and m15Sigma > 0
eventCooldown := math.max(0, eventCooldown - 1)
bool m15Rebase = na(m15Anchor)
if not m15Rebase
float sigmaRatio = math.max(m15Sigma / m15EpochSigma, m15EpochSigma / m15Sigma)
int liveMacroState = f_state(m15Close, m15Anchor, m15MacroDelta)
m15Rebase := sigmaRatio >= rebaseRatio or math.abs(liveMacroState) > maxMacroIndex or (maxEpochBars > 0 and m15EpochAge >= maxEpochBars)
if m15Rebase
m15EpochId += 1
m15Anchor := m15Close
m15EpochSigma := m15Sigma
m15FastDelta := fastK * m15Sigma
m15CoreDelta := coreK * m15Sigma
m15MacroDelta := macroK * m15Sigma
m15EpochAge := 0
else
m15EpochAge += 1
int nextFast = f_state(m15Close, m15Anchor, m15FastDelta)
int nextCore = f_state(m15Close, m15Anchor, m15CoreDelta)
int nextMacro = f_state(m15Close, m15Anchor, m15MacroDelta)
if array.size(m15CorePath) == 0
m15CorePersistence := 1
else if nextCore == m15CoreState
m15CorePersistence += 1
else
m15CorePersistence := 1
if nextMacro != m15MacroState
m15LastMacroDirection := int(math.sign(nextMacro - m15MacroState))
m15LastFastState := m15FastState
m15FastState := nextFast
m15CoreState := nextCore
m15MacroState := nextMacro
f_push_state(m15CorePath, nextCore, pathLength)
if eventActive
eventBars += 1
bool beyond = eventDirection == 1 ? m15Close > eventBoundary : m15Close < eventBoundary
bool hitNext = eventDirection == 1 ? m15High >= eventNextBoundary : m15Low <= eventNextBoundary
eventProvisional := eventProvisional or beyond
eventNextTouched := eventNextTouched or hitNext
bool jump = eventDirection == 1 ? m15Close >= eventBoundary + jumpBufferFraction * eventCoreDelta : m15Close <= eventBoundary - jumpBufferFraction * eventCoreDelta
eventJumpCount := jump ? eventJumpCount + 1 : 0
bool returned = eventDirection == 1 ? m15Close < eventBoundary : m15Close > eventBoundary
bool reflected = eventDirection == 1 ? m15Close <= eventBoundary - reflectionDepthFraction * eventCoreDelta : m15Close >= eventBoundary + reflectionDepthFraction * eventCoreDelta
if eventJumpCount >= jumpConfirmBars
lastOutcome := eventDirection == 1 ? 1 : 2
eventFinalized := true
else if eventProvisional and returned and not eventNextTouched
lastOutcome := eventDirection == 1 ? 5 : 6
eventFinalized := true
else if not eventProvisional and eventBars <= reflectionMaxBars and reflected
lastOutcome := eventDirection == 1 ? 3 : 4
eventFinalized := true
else if eventBars >= maxEventBars
lastOutcome := 7
eventFinalized := true
else if warm
int state = f_state(m15Close, m15Anchor, m15CoreDelta)
float lower = m15Anchor + state * m15CoreDelta
float upper = m15Anchor + (state + 1) * m15CoreDelta
float distanceLower = math.abs(m15Close - lower)
float distanceUpper = math.abs(upper - m15Close)
approachSignal := math.min(distanceLower, distanceUpper) <= approachFraction * m15CoreDelta
bool touchUpper = m15High >= upper and m15Low < upper
bool touchLower = m15Low <= lower and m15High > lower
if (touchUpper or touchLower) and eventCooldown == 0
bool upward = touchUpper and (not touchLower or distanceUpper <= distanceLower)
float candidateBoundary = upward ? upper : lower
int boundaryIndex = int(math.round((candidateBoundary - m15Anchor) / m15CoreDelta))
string boundaryKey = str.tostring(m15EpochId) + ":" + str.tostring(boundaryIndex) + ":" + (upward ? "U" : "D")
bool duplicateBoundary = oneEventPerBoundary and array.includes(processedBoundaryKeys, boundaryKey)
if not duplicateBoundary
f_push_key(processedBoundaryKeys, boundaryKey, 250)
eventSequence += 1
eventActive := true
eventDirection := upward ? 1 : -1
eventOriginState := state
eventTargetState := state + eventDirection
eventBoundary := candidateBoundary
eventNextBoundary := eventBoundary + eventDirection * m15CoreDelta
eventPreviousBoundary := eventBoundary - eventDirection * m15CoreDelta
eventCoreDelta := m15CoreDelta
eventBars := 1
eventProvisional := upward ? m15Close > eventBoundary : m15Close < eventBoundary
eventNextTouched := upward ? m15High >= eventNextBoundary : m15Low <= eventNextBoundary
bool jumpNow = upward ? m15Close >= eventBoundary + jumpBufferFraction * eventCoreDelta : m15Close <= eventBoundary - jumpBufferFraction * eventCoreDelta
eventJumpCount := jumpNow ? 1 : 0
eventH1Regime := h1Regime
eventAlignment := upward ? (h1Regime == 1 ? 1 : h1Regime == -1 ? -1 : 0) : (h1Regime == -1 ? 1 : h1Regime == 1 ? -1 : 0)
bool reflectedNow = upward ? m15Close <= eventBoundary - reflectionDepthFraction * eventCoreDelta : m15Close >= eventBoundary + reflectionDepthFraction * eventCoreDelta
if eventJumpCount >= jumpConfirmBars
lastOutcome := upward ? 1 : 2
eventFinalized := true
else if not eventProvisional and reflectedNow
lastOutcome := upward ? 3 : 4
eventFinalized := true
if eventFinalized
lastOutcomeTime := time
eventActive := false
eventCooldown := eventCooldownBars
// ───────────────────────────── M5 execution timing
var bool executionArmed = false
var bool retestSeen = false
var int executionBars = 0
var int executionDirection = 0
var int executionFamily = 0 // 1 QJ, 2 QR, 3 QF
var float executionBoundary = na
var float executionDelta = na
var int executionAlignment = 0
bool longSignal = false
bool shortSignal = false
bool qjSignal = false
bool qrSignal = false
bool qfSignal = false
if eventFinalized and lastOutcome != 7
executionArmed := true
retestSeen := false
executionBars := 0
executionDirection := lastOutcome == 1 or lastOutcome == 4 or lastOutcome == 6 ? 1 : -1
executionFamily := lastOutcome <= 2 ? 1 : lastOutcome <= 4 ? 2 : 3
executionBoundary := eventBoundary
executionDelta := eventCoreDelta
executionAlignment := eventAlignment
var int timeoutCount = 0
var int qjEventCount = 0
var int qrEventCount = 0
var int qfEventCount = 0
var int qjEntryCount = 0
var int qrEntryCount = 0
var int qfEntryCount = 0
var int alignedCount = 0
var int opposedCount = 0
var int neutralCount = 0
var int qjResolved = 0
var int qrResolved = 0
var int qfResolved = 0
var int qjSuccess = 0
var int qrSuccess = 0
var int qfSuccess = 0
var array<int> evalDirections = array.new_int()
var array<int> evalFamilies = array.new_int()
var array<int> evalEntryBars = array.new_int()
var array<float> evalTargets = array.new_float()
var array<float> evalInvalidations = array.new_float()
if eventFinalized and lastOutcome != 7
if executionFamily == 1
qjEventCount += 1
else if executionFamily == 2
qrEventCount += 1
else
qfEventCount += 1
if executionAlignment == 1
alignedCount += 1
else if executionAlignment == -1
opposedCount += 1
else
neutralCount += 1
if executionArmed and barstate.isconfirmed
executionBars += 1
float tolerance = retestToleranceFraction * executionDelta
bool visits = low <= executionBoundary + tolerance and high >= executionBoundary - tolerance
retestSeen := retestSeen or visits
bool confirms = executionDirection == 1 ? close > executionBoundary : close < executionBoundary
bool chaseOk = not na(m5Sigma) and math.abs(close - open) <= maxEntryBarSigma * m5Sigma
if retestSeen and confirms and chaseOk
longSignal := executionDirection == 1
shortSignal := executionDirection == -1
qjSignal := executionFamily == 1
qrSignal := executionFamily == 2
qfSignal := executionFamily == 3
if executionFamily == 1
qjEntryCount += 1
else if executionFamily == 2
qrEntryCount += 1
else
qfEntryCount += 1
// Future bars evaluate target-before-invalidation. The entry candle is
// excluded because OHLC cannot reveal what happened after the close.
array.push(evalDirections, executionDirection)
array.push(evalFamilies, executionFamily)
array.push(evalEntryBars, bar_index)
array.push(evalTargets, executionBoundary + executionDirection * executionDelta)
array.push(evalInvalidations, executionBoundary - executionDirection * executionDelta)
executionArmed := false
else if executionBars > executionTimeoutBars
timeoutCount += 1
executionArmed := false
// Research outcome evaluator. When target and invalidation are both touched in
// one M5 candle, failure is recorded conservatively because intrabar order is unknown.
if barstate.isconfirmed and array.size(evalDirections) > 0
for i = array.size(evalDirections) - 1 to 0
if bar_index > array.get(evalEntryBars, i)
int evalDirection = array.get(evalDirections, i)
int evalFamily = array.get(evalFamilies, i)
float evalTarget = array.get(evalTargets, i)
float evalInvalidation = array.get(evalInvalidations, i)
bool targetHit = evalDirection == 1 ? high >= evalTarget : low <= evalTarget
bool invalidHit = evalDirection == 1 ? low <= evalInvalidation : high >= evalInvalidation
if targetHit or invalidHit
bool success = targetHit and not invalidHit
if evalFamily == 1
qjResolved += 1
qjSuccess += success ? 1 : 0
else if evalFamily == 2
qrResolved += 1
qrSuccess += success ? 1 : 0
else
qfResolved += 1
qfSuccess += success ? 1 : 0
array.remove(evalDirections, i)
array.remove(evalFamilies, i)
array.remove(evalEntryBars, i)
array.remove(evalTargets, i)
array.remove(evalInvalidations, i)
// ───────────────────────────── Frozen current lattice display
float liveCoreState = not na(m15Anchor) and not na(m15CoreDelta) ? f_state(close, m15Anchor, m15CoreDelta) : na
float coreLower = not na(liveCoreState) ? m15Anchor + liveCoreState * m15CoreDelta : na
float coreUpper = not na(liveCoreState) ? coreLower + m15CoreDelta : na
float fastState = not na(m15Anchor) and not na(m15FastDelta) ? f_state(close, m15Anchor, m15FastDelta) : na
float fastLower = not na(fastState) ? m15Anchor + fastState * m15FastDelta : na
float fastUpper = not na(fastLower) ? fastLower + m15FastDelta : na
float macroState = not na(m15Anchor) and not na(m15MacroDelta) ? f_state(close, m15Anchor, m15MacroDelta) : na
float macroLower = not na(macroState) ? m15Anchor + macroState * m15MacroDelta : na
float macroUpper = not na(macroLower) ? macroLower + m15MacroDelta : na
bool coreLevelChanged = not na(liveCoreState[1]) and (liveCoreState != liveCoreState[1] or m15EpochId != m15EpochId[1])
bool fastLevelChanged = not na(fastState[1]) and (fastState != fastState[1] or m15EpochId != m15EpochId[1])
bool macroLevelChanged = not na(macroState[1]) and (macroState != macroState[1] or m15EpochId != m15EpochId[1])
float coreUpperPlot = coreLevelChanged ? na : coreUpper
float coreLowerPlot = coreLevelChanged ? na : coreLower
float fastUpperPlot = fastLevelChanged ? na : fastUpper
float fastLowerPlot = fastLevelChanged ? na : fastLower
float macroUpperPlot = macroLevelChanged ? na : macroUpper
float macroLowerPlot = macroLevelChanged ? na : macroLower
bool displayAll = signalDisplay == "All"
bool displayEvents = signalDisplay != "Entries only"
plot(showCore ? coreUpperPlot : na, "Core Upper QPL", color.new(color.aqua, 10), 2, plot.style_linebr)
plot(showCore ? coreLowerPlot : na, "Core Lower QPL", color.new(color.aqua, 10), 2, plot.style_linebr)
plot(showFast ? fastUpperPlot : na, "Fast Upper QPL", color.new(color.yellow, 35), 1, plot.style_linebr)
plot(showFast ? fastLowerPlot : na, "Fast Lower QPL", color.new(color.yellow, 35), 1, plot.style_linebr)
plot(showMacro ? macroUpperPlot : na, "Macro Upper QPL", color.new(color.fuchsia, 35), 2, plot.style_linebr)
plot(showMacro ? macroLowerPlot : na, "Macro Lower QPL", color.new(color.fuchsia, 35), 2, plot.style_linebr)
plot(executionArmed ? executionBoundary : na, "Frozen Execution Boundary", color.orange, 3, plot.style_linebr)
plotshape(showApproach and displayAll and approachSignal, "M15 Approach", shape.circle, location.abovebar, color.new(color.silver, 0), size = size.tiny, text = "A")
plotshape(showEvents and displayEvents and eventFinalized and lastOutcome == 1, "QJ Up", shape.labelup, location.belowbar, color.lime, textcolor = color.black, size = size.tiny, text = "QJ↑")
plotshape(showEvents and displayEvents and eventFinalized and lastOutcome == 2, "QJ Down", shape.labeldown, location.abovebar, color.red, textcolor = color.white, size = size.tiny, text = "QJ↓")
plotshape(showEvents and displayEvents and eventFinalized and lastOutcome == 3, "QR Upper", shape.labeldown, location.abovebar, color.orange, textcolor = color.black, size = size.tiny, text = "QR↘")
plotshape(showEvents and displayEvents and eventFinalized and lastOutcome == 4, "QR Lower", shape.labelup, location.belowbar, color.orange, textcolor = color.black, size = size.tiny, text = "QR↗")
plotshape(showEvents and displayEvents and eventFinalized and lastOutcome == 5, "QF Up", shape.labeldown, location.abovebar, color.purple, textcolor = color.white, size = size.tiny, text = "QF↘")
plotshape(showEvents and displayEvents and eventFinalized and lastOutcome == 6, "QF Down", shape.labelup, location.belowbar, color.purple, textcolor = color.white, size = size.tiny, text = "QF↗")
plotshape(showEntries and longSignal, "Long Entry", shape.triangleup, location.belowbar, color.lime, size = size.small, text = "LONG", textcolor = color.black)
plotshape(showEntries and shortSignal, "Short Entry", shape.triangledown, location.abovebar, color.red, size = size.small, text = "SHORT", textcolor = color.white)
alertcondition(longSignal, "ANQ MTF Long", "AlgoNexta Quantum MTF V1: confirmed LONG entry on {{ticker}} {{interval}} at {{close}}")
alertcondition(shortSignal, "ANQ MTF Short", "AlgoNexta Quantum MTF V1: confirmed SHORT entry on {{ticker}} {{interval}} at {{close}}")
alertcondition(qjSignal and longSignal, "ANQ QJ Long", "ANQ QJ LONG on {{ticker}} at {{close}}")
alertcondition(qjSignal and shortSignal, "ANQ QJ Short", "ANQ QJ SHORT on {{ticker}} at {{close}}")
alertcondition(qrSignal and longSignal, "ANQ QR Long", "ANQ QR LONG on {{ticker}} at {{close}}")
alertcondition(qrSignal and shortSignal, "ANQ QR Short", "ANQ QR SHORT on {{ticker}} at {{close}}")
alertcondition(qfSignal and longSignal, "ANQ QF Long", "ANQ QF LONG on {{ticker}} at {{close}}")
alertcondition(qfSignal and shortSignal, "ANQ QF Short", "ANQ QF SHORT on {{ticker}} at {{close}}")
var table dashboard = table.new(position.top_right, 2, 13, border_width = 1)
if barstate.islast and showDashboard
color regimeColor = h1Regime == 1 ? color.new(color.lime, 70) : h1Regime == -1 ? color.new(color.red, 70) : h1Regime == 2 ? color.new(color.orange, 70) : color.new(color.gray, 75)
table.cell(dashboard, 0, 0, "ANQ MTF V1", text_color = color.white, bgcolor = color.rgb(24, 28, 38))
table.cell(dashboard, 1, 0, warm ? "READY" : "WARMUP", text_color = warm ? color.lime : color.orange, bgcolor = color.rgb(24, 28, 38))
table.cell(dashboard, 0, 1, "H1 regime")
table.cell(dashboard, 1, 1, f_regime_name(h1Regime), bgcolor = regimeColor)
table.cell(dashboard, 0, 2, "H1 persistence")
table.cell(dashboard, 1, 2, str.tostring(h1CorePersistence))
table.cell(dashboard, 0, 3, "M15 epoch/state")
table.cell(dashboard, 1, 3, str.tostring(m15EpochId) + " / " + str.tostring(m15CoreState))
table.cell(dashboard, 0, 4, "Active event")
table.cell(dashboard, 1, 4, eventActive ? (eventDirection == 1 ? "UP" : "DOWN") : "None")
table.cell(dashboard, 0, 5, "Execution")
table.cell(dashboard, 1, 5, executionArmed ? (executionDirection == 1 ? "ARMED LONG" : "ARMED SHORT") : "Disarmed")
table.cell(dashboard, 0, 6, "QJ events / entries")
table.cell(dashboard, 1, 6, str.tostring(qjEventCount) + " / " + str.tostring(qjEntryCount))
table.cell(dashboard, 0, 7, "QR events / entries")
table.cell(dashboard, 1, 7, str.tostring(qrEventCount) + " / " + str.tostring(qrEntryCount))
table.cell(dashboard, 0, 8, "QF events / entries")
table.cell(dashboard, 1, 8, str.tostring(qfEventCount) + " / " + str.tostring(qfEntryCount))
table.cell(dashboard, 0, 9, "A / O / N / timeout")
table.cell(dashboard, 1, 9, str.tostring(alignedCount) + "/" + str.tostring(opposedCount) + "/" + str.tostring(neutralCount) + "/" + str.tostring(timeoutCount))
table.cell(dashboard, 0, 10, "QJ target-first")
table.cell(dashboard, 1, 10, qjResolved > 0 ? str.tostring(100.0 * qjSuccess / qjResolved, "#.0") + "% (" + str.tostring(qjResolved) + ")" : "n/a")
table.cell(dashboard, 0, 11, "QR target-first")
table.cell(dashboard, 1, 11, qrResolved > 0 ? str.tostring(100.0 * qrSuccess / qrResolved, "#.0") + "% (" + str.tostring(qrResolved) + ")" : "n/a")
table.cell(dashboard, 0, 12, "QF target-first")
table.cell(dashboard, 1, 12, qfResolved > 0 ? str.tostring(100.0 * qfSuccess / qfResolved, "#.0") + "% (" + str.tostring(qfResolved) + ")" : "n/a")
else if barstate.islast and not showDashboard
table.clear(dashboard, 0, 0, 1, 12)