Skip to content
← Indicator library
tradingviewstructureindicatorpinescript-v6

Quantum.AlgoNexta

M5 multi-timeframe lattice indicator using confirmed H1 and M15 states to time retest-based M5 signals.

Published by AlgoNexta. AlgoNexta builds and documents evidence-first trading tools so you can inspect the logic before using it.About AlgoNextaIndicator libraryAlgoNexta Research
Published Oct 16, 2026#lattice#multi-timeframe#price-levels#retest#indicator#tradingview#pinescript-v6#m5

Overview

What this indicator does

Quantum.AlgoNexta is an overlay indicator built exclusively for a standard 5-minute chart. It builds price “lattice” boundaries from the standard deviation of price changes on confirmed H1 and M15 bars, then watches M15 interactions with a frozen Core boundary. A finalized M15 event can arm an M5 retest-and-close confirmation signal. The script does not place orders: `LONG` and `SHORT` triangles are plotted signals, and its alert conditions fire only when those signals occur on a confirmed M5 bar.

Type
indicator
Category
structure
Available in
Pine Script
Source
Open — copy or download

How it works

Read the logic before you use it.

Diagram: When an M15 boundary event starts
1

When an M15 boundary event starts

After sigma warm-up, each newly confirmed M15 bar is assigned a Core state from the epoch anchor and `Core K = 2.5` times M15 sigma. The script starts an event when the M15 range crosses the nearest upper or lower Core boundary, subject to the cooldown and optional one-event-per-boundary filter.

Diagram: How the M15 outcome is confirmed
2

How the M15 outcome is confirmed

An active event is resolved as a QJ when closes extend beyond the boundary buffer for `Jump Confirm Bars = 1`; it can instead become QF after returning across the boundary without touching the next boundary, QR after a qualifying reflection, or expire at `Max M15 Event Bars = 8`. The event stores the H1 regime alignment at the interaction, but alignment is displayed and counted rather than used as an entry filter.

Diagram: When an M5 entry signal appears
3

When an M5 entry signal appears

Any finalized non-expired event arms its frozen Core boundary. On a confirmed M5 bar within `Execution Timeout Bars = 6`, the range must revisit that boundary within `Retest Tolerance Fraction = 0.15`, the close must be on the event direction’s side, and the candle body must not exceed `Max Entry Bar Sigma = 2.0` times M5 sigma; only then does the indicator plot a LONG or SHORT triangle.

Walkthrough

Watch how it reads the chart.

Live market chart

The logic on real candles.

Backtest evidence

What the numbers actually show.

This script's logic could not be confidently reconstructed into an automated reference backtest, so no performance figures are shown rather than estimated ones.

Verify it in TradingView's Strategy Tester (or the equivalent tool for tradingview) before relying on it.

Vision Grade

What was measured, and how confident we are in it.

Vision Grade requires a reference backtest with enough reconstructed entries to measure — not available for this script yet.

Full breakdown

How the script behaves.

About AlgoNexta

Published by AlgoNexta, an evidence-first platform for building, reviewing, and documenting algorithmic trading tools. This page explains the script's actual logic and intended use; it does not promise profitability or replace verification in TradingView.

What it does

Quantum.AlgoNexta is an overlay indicator built exclusively for a standard 5-minute chart. It builds price “lattice” boundaries from the standard deviation of price changes on confirmed H1 and M15 bars, then watches M15 interactions with a frozen Core boundary. A finalized M15 event can arm an M5 retest-and-close confirmation signal.

The script does not place orders: LONG and SHORT triangles are plotted signals, and its alert conditions fire only when those signals occur on a confirmed M5 bar.

Inputs and warm-up

The default lattice widths are Fast K = 2.0, Core K = 2.5, and Macro K = 3.0. Their volatility units come from H1 Sigma Period = 24, M15 Sigma Period = 48, and M5 Sigma Period = 72, each calculated as the standard deviation of close-to-close changes.

It remains in warm-up until all three sigma series exist and are above zero. The lattice is rebased when volatility changes by at least Volatility Rebase Ratio = 1.50, a Macro state exceeds Max Macro Orbital = 6, or—if enabled—an epoch reaches Max Epoch Bars.

What conditions it watches

  1. H1 regime: On each newly confirmed H1 bar, the script records Core and Macro lattice states. With defaults, a bullish or bearish regime requires a directional Core path, a non-opposing Macro path, and Min H1 Persistence = 2. A flat net Core path with at least Reflection Alternations = 2 is classified as Reflection.
  2. M15 boundary event: On each newly confirmed M15 bar, it checks whether the bar crosses a Core boundary. It then resolves the interaction as a Quantum Jump (QJ), Quantum Reflection (QR), Quantum Failure (QF), or expiry, using Jump Buffer Fraction = 0.10, Jump Confirm Bars = 1, Reflection Depth Fraction = 0.25, Reflection Max Bars = 4, and Max M15 Event Bars = 8.
  3. M5 entry timing: A non-expired event arms an execution boundary. Within Execution Timeout Bars = 6, price must visit that boundary within Retest Tolerance Fraction = 0.15, close back on the event direction’s side, and have an M5 candle body no larger than Max Entry Bar Sigma = 2.0 times M5 sigma.

A boundary touch alone is not an entry. For example, after an event, no triangle appears if price never revisits the frozen boundary, closes on the wrong side, the entry bar exceeds the sigma-size filter, or the six-bar execution window expires.

Reading the chart

  • Aqua lines: M15 Core lattice boundaries. Show Core Boundaries is enabled by default.
  • Yellow lines: Fast lattice boundaries, available through Show Fast Boundaries (default off).
  • Fuchsia lines: Macro lattice boundaries, available through Show Macro Boundaries (default off).
  • Orange line: the frozen execution boundary while an M5 setup is armed.
  • Silver A marker: an M15 close is within Approach Fraction = 0.20 of a Core boundary. It requires both Show Approach Markers and Signal Density = All.
  • QJ labels: lime for upward and red for downward jump outcomes.
  • QR labels: orange reflection outcomes; their arrows indicate the resulting execution direction.
  • QF labels: purple failure outcomes; their arrows indicate the resulting execution direction.
  • Green LONG / red SHORT triangles: confirmed M5 plotted signals. These are not broker orders.

Signal Density defaults to Events + Entries; choose Entries only to hide event labels, or All to also permit approach markers. Show M15 Event Labels, Show M5 Entry Signals, and Show Dashboard are enabled by default.

The dashboard reports warm-up status, H1 regime and persistence, M15 epoch/state, active-event and armed-execution status, event/entry counts, alignment counts, and an internal target-first statistic. That statistic is a research counter, not a TradingView Strategy Tester result: it evaluates a one-Core-delta projection against a one-Core-delta invalidation after a plotted signal, and treats same-bar target/invalidation touches conservatively as failures because intrabar order is unknown.

Timeframe and market use

The source enforces a standard 5-minute chart and throws a runtime error on every other chart timeframe. It requests the chart symbol’s confirmed 15-minute and 60-minute data, so it is designed for symbols that have usable M5, M15, and H1 history. No specific asset class or ticker is hard-coded.

Alerts and limitations

Create TradingView alerts from ANQ MTF Long or ANQ MTF Short; family-specific alerts are also available for QJ, QR, and QF long/short signals. Signals require barstate.isconfirmed, so they are generated after the M5 candle closes.

  • Confirmed H1 and M15 requests use prior closed higher-timeframe values ([1]) with lookahead_off; those higher-timeframe decision values do not change once received.
  • This does not mean every visible live M5 lattice level is permanently fixed: the displayed current M15 lattice position is calculated from current M5 price within the frozen M15 epoch.
  • It does not forecast direction independently of its defined boundary-event sequence, detect order flow, or manage orders, position size, fills, stops, or live broker execution.
  • Events can be suppressed by Event Cooldown (M15 bars) = 2 or One Event Per Boundary / Epoch = true; the latter prevents repeated processing of the same directional boundary in one M15 epoch.
  • The internal evaluator is not a strategy and cannot substitute for execution-aware testing. Use TradingView Strategy Tester or an equivalent platform for historical and live-result evaluation; this indicator is not financial advice.

Source

Full source code, in every platform.

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.

Download .pine
// ============================================================================
// © 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)

FAQ

Common questions.

What does Quantum.AlgoNexta detect?▾

It detects confirmed M15 interactions with volatility-scaled Core lattice boundaries, classifies them as QJ, QR, QF, or expired, then optionally plots an M5 retest-and-close signal.

Which timeframe should I use?▾

Use a standard 5-minute chart only. The script explicitly stops with a runtime error on other chart timeframes and reads confirmed 15-minute and 60-minute data for the same symbol.

Does it repaint?▾

Its H1 and M15 decision inputs use the previous closed higher-timeframe bar with `lookahead_off`, and entry signals require a confirmed M5 bar. Current lattice display levels can still move with M5 price inside an already frozen M15 epoch, so users should distinguish a live level from a completed-bar signal.

Does the indicator place trades or manage stops?▾

No. It is an indicator, not a strategy: it plots triangles and alert conditions but contains no `strategy.entry` or broker-order logic. Its target/invalidation values are used only for an internal research evaluator.

How do LONG and SHORT alerts work?▾

Use TradingView alerts based on `ANQ MTF Long` or `ANQ MTF Short`, or select the QJ, QR, or QF family-specific alert conditions. An alert can occur only after an M15 event arms execution and an M5 retest, directional close, and entry-bar sigma filter all pass.

Are the dashboard target-first figures proof of live performance?▾

No. They are internal historical research counters with a conservative same-candle assumption, not Strategy Tester or live-trading results. This is not financial advice; TradingView Strategy Tester, or an equivalent execution-aware platform, is the source of truth for historical and live-result evaluation.

Want a version tuned to your market?

Describe the change in plain English and AlgoNexta rebuilds it as a fresh Pine v6 script — with its own explanation, evidence, and walkthrough.

Build your own version

Educational content only — not financial advice. TradingView is the source of truth for live data, compilation, and Strategy Tester results.

We use cookies to understand how the site is used and improve it. We only load analytics after you accept. Privacy Policy