Indicator · Pine Script v6 · Own pane

Nexural OrderFlow Matrix

by JasonTeixeira· code credited to Nexural Trading

Nexural OrderFlow Matrix is an order flow visualization tool that plots a detailed heatmap table and stacked imbalance bars in a separate pane.

View on GitHub

GitHub stars9on the repository
Pine versionv6current
Lines of code588
Settings30inputs
LicenceCustom licencefile: MPL-2.0
Last update12 days ago16 Oct 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

588 lines of Pine Script v6 from platforms/tradingview/indicators/OrderflowMatrix/src/OrderflowMatrix.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

OrderflowMatrix.pine
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0
// © Nexural Trading

//@version=6
indicator("Nexural OrderFlow Matrix", "Nexural Flow", overlay=false, max_boxes_count=500, max_labels_count=500, max_bars_back=500)

// ============================================================================
// NEXURAL ORDERFLOW MATRIX V5.8 - NEXURAL FLOW EDITION
// The Ultimate Order Flow Heatmap Matrix
// ============================================================================
//
// Features:
// • Per-candle heatmap matrix with gray→vibrant color gradient
// • NEW: Stacked Imbalance Bars - visual buy/sell separation
// • Nexural Flow live meter with imbalance ratio
// • Bar VWAP, Delta, Delta %, Buy/Sell Vol, Bar Δ CVD
// • Row labels on right edge for visibility
// • Dual data source: ta.requestUpAndDownVolume + ta.requestVolumeDelta
//
// © Nexural Trading - Maximum Accuracy Edition
// ============================================================================

import TradingView/ta/10

// ─────────────────────────────────────────────────────────────────────────────
// INPUTS - TIMEFRAME
// ─────────────────────────────────────────────────────────────────────────────

grp_ltf = "═══ Lower Timeframe ═══"
string ltfMode = input.string("Auto", "Timeframe Mode", options=["Auto", "Aggressive", "Conservative", "Custom"], group=grp_ltf)
string customTF = input.timeframe("1", "Custom Timeframe", group=grp_ltf)

// ─────────────────────────────────────────────────────────────────────────────
// INPUTS - DISPLAY
// ─────────────────────────────────────────────────────────────────────────────

grp_display = "═══ Display Settings ═══"
bool showMatrix = input.bool(true, "Show Matrix Table", group=grp_display, tooltip="Show the heatmap data table")
bool showImbalanceBars = input.bool(true, "Show Imbalance Bars", group=grp_display, tooltip="Show the stacked buy/sell bars")
string textSizeInput = input.string("Tiny", "Text Size", options=["Auto", "Tiny", "Small"], group=grp_display)
bool showRowLabels = input.bool(true, "Show Row Labels", group=grp_display)
float rowHeight = input.float(1.0, "Row Height", minval=0.5, maxval=2.0, step=0.1, group=grp_display)
float activityThreshold = input.float(25.0, "Activity Threshold %", minval=10.0, maxval=50.0, step=5.0, tooltip="Below this delta %, colors fade to gray", group=grp_display)

// ─────────────────────────────────────────────────────────────────────────────
// INPUTS - IMBALANCE BARS
// ─────────────────────────────────────────────────────────────────────────────

grp_imbalance = "═══ Imbalance Bars ═══"
float imbalanceBarHeight = input.float(3.0, "Bar Height", minval=1.0, maxval=6.0, step=0.5, group=grp_imbalance)
bool showImbalanceLabels = input.bool(true, "Show Volume Labels", group=grp_imbalance)
bool showImbalancePct = input.bool(true, "Show Percentage", group=grp_imbalance)

// ─────────────────────────────────────────────────────────────────────────────
// INPUTS - METRICS
// ─────────────────────────────────────────────────────────────────────────────

grp_metrics = "═══ Metrics to Show ═══"
bool showVolume = input.bool(true, "Volume", inline="m1", group=grp_metrics)
bool showBarVWAP = input.bool(true, "Bar VWAP", inline="m1", group=grp_metrics)
bool showDelta = input.bool(true, "Delta", inline="m2", group=grp_metrics)
bool showDeltaPct = input.bool(true, "Delta %", inline="m2", group=grp_metrics)
bool showMaxDelta = input.bool(false, "Max Δ", inline="m3", group=grp_metrics)
bool showMinDelta = input.bool(false, "Min Δ", inline="m3", group=grp_metrics)
bool showBarCVD = input.bool(true, "Bar Δ CVD", inline="m4", group=grp_metrics)
bool showBuyVol = input.bool(true, "Buy Vol", inline="m4", group=grp_metrics)
bool showSellVol = input.bool(true, "Sell Vol", inline="m5", group=grp_metrics)

// ─────────────────────────────────────────────────────────────────────────────
// INPUTS - NEXURAL FLOW METER
// ─────────────────────────────────────────────────────────────────────────────

grp_meter = "═══ Nexural Flow Meter ═══"
bool showMeter = input.bool(true, "Show Nexural Flow Meter", group=grp_meter)
string meterSize = input.string("Normal", "Meter Size", options=["Small", "Normal", "Large"], group=grp_meter)
string meterPos = input.string("Top Right", "Meter Position", options=["Top Right", "Top Left", "Bottom Right", "Bottom Left"], group=grp_meter)

// ─────────────────────────────────────────────────────────────────────────────
// INPUTS - CVD
// ─────────────────────────────────────────────────────────────────────────────

grp_cvd = "═══ CVD Settings ═══"
string cvdResetInput = input.string("Daily", "CVD Reset", options=["None", "Daily", "Weekly", "Monthly"], group=grp_cvd)

// ─────────────────────────────────────────────────────────────────────────────
// INPUTS - COLORS
// ─────────────────────────────────────────────────────────────────────────────

grp_colors = "═══ Colors ═══"
color bullColorBright = input.color(#00e676, "Bullish (Strong)", inline="c1", group=grp_colors)
color bearColorBright = input.color(#ff1744, "Bearish (Strong)", inline="c1", group=grp_colors)
color lowActivityColor = input.color(#3d4450, "Low Activity", group=grp_colors)
color nexuralAccent = input.color(#00b8d4, "Nexural Accent", group=grp_colors)
color volumeColorHigh = input.color(#ffab00, "Volume (High)", inline="c2", group=grp_colors)
color volumeColorLow = input.color(#4a4530, "Volume (Low)", inline="c2", group=grp_colors)

// ─────────────────────────────────────────────────────────────────────────────
// TIMEFRAME LOGIC
// ─────────────────────────────────────────────────────────────────────────────

getLowerTimeframe() =>
    switch ltfMode
        "Auto" =>
            switch
                timeframe.isseconds => "1S"
                timeframe.isintraday => "1"
                timeframe.isdaily => "5"
                => "60"
        "Aggressive" =>
            switch
                timeframe.isseconds => "1S"
                timeframe.isintraday => "1S"
                timeframe.isdaily => "1"
                => "5"
        "Conservative" =>
            switch
                timeframe.isseconds => "1S"
                timeframe.isintraday => "5"
                timeframe.isdaily => "15"
                => "60"
        "Custom" => customTF
        => "1"

string lowerTimeframe = getLowerTimeframe()

string cvdPeriod = switch cvdResetInput
    "None" => ""
    "Daily" => "1D"
    "Weekly" => "1W"
    "Monthly" => "1M"
    => "1D"

// ─────────────────────────────────────────────────────────────────────────────
// DATA REQUESTS
// ─────────────────────────────────────────────────────────────────────────────

[upVolume, downVolume, barDelta] = ta.requestUpAndDownVolume(lowerTimeframe)
[cvdOpen, cvdHigh, cvdLow, cvdClose] = ta.requestVolumeDelta(lowerTimeframe, cvdPeriod)

// ─────────────────────────────────────────────────────────────────────────────
// CALCULATIONS
// ─────────────────────────────────────────────────────────────────────────────

float totalVolume = math.abs(nz(upVolume)) + math.abs(nz(downVolume))
float buyVol = math.abs(nz(upVolume))
float sellVol = math.abs(nz(downVolume))
float delta = nz(barDelta)
float deltaPct = totalVolume > 0 ? (delta / totalVolume) * 100.0 : 0.0
float absDeltaPct = math.abs(deltaPct)
float maxDeltaBar = nz(cvdHigh) - nz(cvdOpen)
float minDeltaBar = nz(cvdLow) - nz(cvdOpen)

// Bar Δ CVD (change this bar, not cumulative)
float barDeltaCVD = nz(cvdClose) - nz(cvdOpen)

// Cumulative CVD for meter display
float cvdCumulative = nz(cvdClose)

// Bar VWAP calculation
float barVWAP = hl2

// Imbalance Ratio
float imbalanceRatio = sellVol > 0 ? buyVol / sellVol : (buyVol > 0 ? 99.9 : 1.0)
float imbalanceRatioInverse = buyVol > 0 ? sellVol / buyVol : (sellVol > 0 ? 99.9 : 1.0)
bool isBuyDominant = buyVol >= sellVol
string imbalanceStr = isBuyDominant ? str.tostring(imbalanceRatio, "#.#") + ":1" : "1:" + str.tostring(imbalanceRatioInverse, "#.#")

// ─────────────────────────────────────────────────────────────────────────────
// COUNT METRICS
// ─────────────────────────────────────────────────────────────────────────────

countMetrics() =>
    int count = 0
    if showVolume
        count += 1
    if showBarVWAP
        count += 1
    if showDelta
        count += 1
    if showDeltaPct
        count += 1
    if showMaxDelta
        count += 1
    if showMinDelta
        count += 1
    if showBarCVD
        count += 1
    if showBuyVol
        count += 1
    if showSellVol
        count += 1
    count

int metricCount = countMetrics()
float matrixHeight = showMatrix ? metricCount * rowHeight : 0.0
float imbalanceHeight = showImbalanceBars ? imbalanceBarHeight : 0.0
float gapHeight = (showImbalanceBars and showMatrix) ? 0.3 : 0.0  // Gap only when showing both
float totalRows = matrixHeight + imbalanceHeight + gapHeight

// ─────────────────────────────────────────────────────────────────────────────
// HELPER FUNCTIONS
// ─────────────────────────────────────────────────────────────────────────────

formatVol(float val) =>
    string result = ""
    if not na(val)
        if math.abs(val) >= 1000000000
            result := str.tostring(val / 1000000000, "#.##") + "B"
        else if math.abs(val) >= 1000000
            result := str.tostring(val / 1000000, "#.##") + "M"
        else if math.abs(val) >= 1000
            result := str.tostring(val / 1000, "#.#") + "K"
        else
            result := str.tostring(val, "#")
    result

formatPrice(float val) =>
    na(val) ? "" : str.tostring(val, "#.##")

formatPct(float val) =>
    na(val) ? "" : str.tostring(val, "#.#") + "%"

getTextSize() =>
    switch textSizeInput
        "Tiny" => size.tiny
        "Small" => size.small
        "Auto" => size.auto
        => size.tiny

getMeterTextSize() =>
    switch meterSize
        "Small" => size.small
        "Normal" => size.normal
        "Large" => size.large
        => size.normal

getMeterPosition() =>
    switch meterPos
        "Top Right" => position.top_right
        "Top Left" => position.top_left
        "Bottom Right" => position.bottom_right
        "Bottom Left" => position.bottom_left
        => position.top_right

// ─────────────────────────────────────────────────────────────────────────────
// ENHANCED COLOR FUNCTION - Gray to Vibrant
// ─────────────────────────────────────────────────────────────────────────────

getActivityColor(float value, float maxValue, bool isBullish, float activityLevel) =>
    float normalizedValue = maxValue > 0 ? math.min(math.abs(value) / maxValue, 1.0) : 0.0
    
    float colorBlend = 0.0
    if activityLevel < activityThreshold
        colorBlend := activityLevel / activityThreshold * 0.3
    else
        float aboveThreshold = (activityLevel - activityThreshold) / (100.0 - activityThreshold)
        colorBlend := 0.3 + (aboveThreshold * 0.7)
    
    int baseTrans = math.round((1.0 - normalizedValue) * 50)
    
    color result = lowActivityColor
    if colorBlend < 0.3
        result := color.new(lowActivityColor, baseTrans + 20)
    else if colorBlend < 0.5
        result := color.new(isBullish ? #4a635a : #634a4a, baseTrans + 10)
    else if colorBlend < 0.7
        result := color.new(isBullish ? #2e7d52 : #7d2e2e, baseTrans)
    else
        result := color.new(isBullish ? bullColorBright : bearColorBright, math.max(0, baseTrans - 20))
    result

getVolumeColor(float value, float maxValue, float activityLevel) =>
    float normalizedValue = maxValue > 0 ? math.min(value / maxValue, 1.0) : 0.0
    
    // Yellow/gold gradient based on volume intensity
    int trans = math.round((1.0 - normalizedValue) * 60 + 10)
    color result = color.from_gradient(normalizedValue, 0.0, 1.0, volumeColorLow, volumeColorHigh)
    color.new(result, trans)

getNeutralColor(float activityLevel) =>
    if activityLevel < activityThreshold
        color.new(lowActivityColor, 50)
    else
        color.new(#546e7a, 30)

// ─────────────────────────────────────────────────────────────────────────────
// ROLLING MAX VALUES FOR SCALING
// ─────────────────────────────────────────────────────────────────────────────

var float maxVolWindow = 1.0
var float maxDeltaWindow = 1.0
var float maxBuyWindow = 1.0
var float maxSellWindow = 1.0
var float maxBarCVDWindow = 1.0

maxVolWindow := math.max(maxVolWindow * 0.995, totalVolume, 1.0)
maxDeltaWindow := math.max(maxDeltaWindow * 0.995, math.abs(delta), 1.0)
maxBuyWindow := math.max(maxBuyWindow * 0.995, buyVol, 1.0)
maxSellWindow := math.max(maxSellWindow * 0.995, sellVol, 1.0)
maxBarCVDWindow := math.max(maxBarCVDWindow * 0.995, math.abs(barDeltaCVD), 1.0)

// Box coordinates
int boxLeft = bar_index
int boxRight = bar_index + 1

// Only draw if we have volume data
bool hasData = totalVolume > 0

// ─────────────────────────────────────────────────────────────────────────────
// DRAW IMBALANCE BARS (Stacked Buy/Sell Visual)
// ─────────────────────────────────────────────────────────────────────────────

float imbalanceTop = totalRows
float imbalanceBottom = showImbalanceBars ? (totalRows - imbalanceHeight) : totalRows

if showImbalanceBars and hasData
    // Calculate proportional heights
    float buyPct = totalVolume > 0 ? buyVol / totalVolume : 0.5
    float sellPct = totalVolume > 0 ? sellVol / totalVolume : 0.5
    
    float buyHeight = imbalanceHeight * buyPct
    float sellHeight = imbalanceHeight * sellPct
    
    // Determine colors based on activity
    color buyBarColor = absDeltaPct >= activityThreshold ? bullColorBright : color.new(bullColorBright, 60)
    color sellBarColor = absDeltaPct >= activityThreshold ? bearColorBright : color.new(bearColorBright, 60)
    
    // Draw Buy bar (top portion)
    float buyTop = imbalanceTop
    float buyBottom = imbalanceTop - buyHeight
    string buyText = ""
    if showImbalanceLabels and showImbalancePct
        buyText := formatVol(buyVol) + "\n" + str.tostring(buyPct * 100, "#.#") + "%"
    else if showImbalanceLabels
        buyText := formatVol(buyVol)
    else if showImbalancePct
        buyText := str.tostring(buyPct * 100, "#.#") + "%"
    
    box.new(boxLeft, buyTop, boxRight, buyBottom, bgcolor=color.new(buyBarColor, 20), border_color=color.new(buyBarColor, 0), border_width=1, text=buyText, text_color=color.white, text_size=getTextSize(), text_halign=text.align_center, text_valign=text.align_center)
    
    // Draw Sell bar (bottom portion)
    float sellTop = buyBottom
    float sellBottom = imbalanceBottom
    string sellText = ""
    if showImbalanceLabels and showImbalancePct
        sellText := formatVol(sellVol) + "\n" + str.tostring(sellPct * 100, "#.#") + "%"
    else if showImbalanceLabels
        sellText := formatVol(sellVol)
    else if showImbalancePct
        sellText := str.tostring(sellPct * 100, "#.#") + "%"
    
    box.new(boxLeft, sellTop, boxRight, sellBottom, bgcolor=color.new(sellBarColor, 20), border_color=color.new(sellBarColor, 0), border_width=1, text=sellText, text_color=color.white, text_size=getTextSize(), text_halign=text.align_center, text_valign=text.align_center)

// ─────────────────────────────────────────────────────────────────────────────
// DRAW MATRIX BOXES
// ─────────────────────────────────────────────────────────────────────────────

float matrixTop = showImbalanceBars ? (imbalanceBottom - gapHeight) : totalRows

int rowNum = 0

bool isSignificant = absDeltaPct >= activityThreshold
color textCol = isSignificant ? color.white : color.new(color.white, 40)

if showMatrix and hasData
    // Volume Row
    if showVolume
        float y1 = matrixTop - (rowNum * rowHeight)
        float y2 = y1 - rowHeight
        color cellColor = getVolumeColor(totalVolume, maxVolWindow, absDeltaPct)
        box.new(boxLeft, y1, boxRight, y2, bgcolor=cellColor, border_color=color.new(#2a2e39, 50), border_width=1, text=formatVol(totalVolume), text_color=textCol, text_size=getTextSize(), text_halign=text.align_center, text_valign=text.align_center)
        rowNum += 1
    
    // Bar VWAP Row
    if showBarVWAP
        float y1 = matrixTop - (rowNum * rowHeight)
        float y2 = y1 - rowHeight
        color cellColor = getNeutralColor(absDeltaPct)
        box.new(boxLeft, y1, boxRight, y2, bgcolor=cellColor, border_color=color.new(#2a2e39, 50), border_width=1, text=formatPrice(barVWAP), text_color=textCol, text_size=getTextSize(), text_halign=text.align_center, text_valign=text.align_center)
        rowNum += 1
    
    // Delta Row
    if showDelta
        float y1 = matrixTop - (rowNum * rowHeight)
        float y2 = y1 - rowHeight
        color cellColor = getActivityColor(delta, maxDeltaWindow, delta > 0, absDeltaPct)
        box.new(boxLeft, y1, boxRight, y2, bgcolor=cellColor, border_color=color.new(#2a2e39, 50), border_width=1, text=formatVol(delta), text_color=textCol, text_size=getTextSize(), text_halign=text.align_center, text_valign=text.align_center)
        rowNum += 1
    
    // Delta % Row
    if showDeltaPct
        float y1 = matrixTop - (rowNum * rowHeight)
        float y2 = y1 - rowHeight
        color cellColor = getActivityColor(deltaPct, 100.0, deltaPct > 0, absDeltaPct)
        box.new(boxLeft, y1, boxRight, y2, bgcolor=cellColor, border_color=color.new(#2a2e39, 50), border_width=1, text=formatPct(deltaPct), text_color=textCol, text_size=getTextSize(), text_halign=text.align_center, text_valign=text.align_center)
        rowNum += 1
    
    // Max Delta Row
    if showMaxDelta
        float y1 = matrixTop - (rowNum * rowHeight)
        float y2 = y1 - rowHeight
        color cellColor = getActivityColor(maxDeltaBar, maxDeltaWindow, true, absDeltaPct)
        box.new(boxLeft, y1, boxRight, y2, bgcolor=cellColor, border_color=color.new(#2a2e39, 50), border_width=1, text=formatVol(maxDeltaBar), text_color=textCol, text_size=getTextSize(), text_halign=text.align_center, text_valign=text.align_center)
        rowNum += 1
    
    // Min Delta Row
    if showMinDelta
        float y1 = matrixTop - (rowNum * rowHeight)
        float y2 = y1 - rowHeight
        color cellColor = getActivityColor(minDeltaBar, maxDeltaWindow, false, absDeltaPct)
        box.new(boxLeft, y1, boxRight, y2, bgcolor=cellColor, border_color=color.new(#2a2e39, 50), border_width=1, text=formatVol(minDeltaBar), text_color=textCol, text_size=getTextSize(), text_halign=text.align_center, text_valign=text.align_center)
        rowNum += 1
    
    // Bar Δ CVD Row (per-bar change, not cumulative)
    if showBarCVD
        float y1 = matrixTop - (rowNum * rowHeight)
        float y2 = y1 - rowHeight
        color cellColor = getActivityColor(barDeltaCVD, maxBarCVDWindow, barDeltaCVD > 0, absDeltaPct)
        box.new(boxLeft, y1, boxRight, y2, bgcolor=cellColor, border_color=color.new(#2a2e39, 50), border_width=1, text=formatVol(barDeltaCVD), text_color=textCol, text_size=getTextSize(), text_halign=text.align_center, text_valign=text.align_center)
        rowNum += 1
    
    // Buy Volume Row
    if showBuyVol
        float y1 = matrixTop - (rowNum * rowHeight)
        float y2 = y1 - rowHeight
        color cellColor = getActivityColor(buyVol, maxBuyWindow, true, absDeltaPct)
        box.new(boxLeft, y1, boxRight, y2, bgcolor=cellColor, border_color=color.new(#2a2e39, 50), border_width=1, text=formatVol(buyVol), text_color=textCol, text_size=getTextSize(), text_halign=text.align_center, text_valign=text.align_center)
        rowNum += 1
    
    // Sell Volume Row
    if showSellVol
        float y1 = matrixTop - (rowNum * rowHeight)
        float y2 = y1 - rowHeight
        color cellColor = getActivityColor(sellVol, maxSellWindow, false, absDeltaPct)
        box.new(boxLeft, y1, boxRight, y2, bgcolor=cellColor, border_color=color.new(#2a2e39, 50), border_width=1, text=formatVol(sellVol), text_color=textCol, text_size=getTextSize(), text_halign=text.align_center, text_valign=text.align_center)
        rowNum += 1

// ─────────────────────────────────────────────────────────────────────────────
// ROW LABELS - AS BOXES AT END OF MATRIX
// ─────────────────────────────────────────────────────────────────────────────

// Labels are now drawn inline with each row as boxes
// We'll add them at the end of the last bar

if barstate.islast and showRowLabels
    int labelLeft = bar_index + 2
    int labelRight = bar_index + 8
    color labelBgDark = color.new(#1e222d, 0)
    
    // Imbalance label (only when showing imbalance bars)
    if showImbalanceBars
        float y1 = imbalanceTop
        float y2 = imbalanceBottom
        box.new(labelLeft, y1, labelRight, y2, bgcolor=color.new(nexuralAccent, 70), border_color=nexuralAccent, border_width=1, text="Imbalance", text_color=color.white, text_size=size.small, text_halign=text.align_center, text_valign=text.align_center)
    
    // Matrix labels (only when showing matrix)
    if showMatrix
        int labelRowNum = 0
        
        if showVolume
            float y1 = matrixTop - (labelRowNum * rowHeight)
            float y2 = y1 - rowHeight
            box.new(labelLeft, y1, labelRight, y2, bgcolor=color.new(volumeColorHigh, 60), border_color=volumeColorHigh, border_width=1, text="Volume", text_color=color.white, text_size=size.small, text_halign=text.align_center, text_valign=text.align_center)
            labelRowNum += 1
        
        if showBarVWAP
            float y1 = matrixTop - (labelRowNum * rowHeight)
            float y2 = y1 - rowHeight
            box.new(labelLeft, y1, labelRight, y2, bgcolor=color.new(nexuralAccent, 70), border_color=nexuralAccent, border_width=1, text="Bar VWAP", text_color=color.white, text_size=size.small, text_halign=text.align_center, text_valign=text.align_center)
            labelRowNum += 1
        
        if showDelta
            float y1 = matrixTop - (labelRowNum * rowHeight)
            float y2 = y1 - rowHeight
            box.new(labelLeft, y1, labelRight, y2, bgcolor=labelBgDark, border_color=color.new(color.white, 70), border_width=1, text="Delta", text_color=color.white, text_size=size.small, text_halign=text.align_center, text_valign=text.align_center)
            labelRowNum += 1
        
        if showDeltaPct
            float y1 = matrixTop - (labelRowNum * rowHeight)
            float y2 = y1 - rowHeight
            box.new(labelLeft, y1, labelRight, y2, bgcolor=labelBgDark, border_color=color.new(color.white, 70), border_width=1, text="Delta %", text_color=color.white, text_size=size.small, text_halign=text.align_center, text_valign=text.align_center)
            labelRowNum += 1
        
        if showMaxDelta
            float y1 = matrixTop - (labelRowNum * rowHeight)
            float y2 = y1 - rowHeight
            box.new(labelLeft, y1, labelRight, y2, bgcolor=color.new(bullColorBright, 70), border_color=bullColorBright, border_width=1, text="Max Delta", text_color=color.white, text_size=size.small, text_halign=text.align_center, text_valign=text.align_center)
            labelRowNum += 1
        
        if showMinDelta
            float y1 = matrixTop - (labelRowNum * rowHeight)
            float y2 = y1 - rowHeight
            box.new(labelLeft, y1, labelRight, y2, bgcolor=color.new(bearColorBright, 70), border_color=bearColorBright, border_width=1, text="Min Delta", text_color=color.white, text_size=size.small, text_halign=text.align_center, text_valign=text.align_center)
            labelRowNum += 1
        
        if showBarCVD
            float y1 = matrixTop - (labelRowNum * rowHeight)
            float y2 = y1 - rowHeight
            box.new(labelLeft, y1, labelRight, y2, bgcolor=color.new(nexuralAccent, 70), border_color=nexuralAccent, border_width=1, text="CVD", text_color=color.white, text_size=size.small, text_halign=text.align_center, text_valign=text.align_center)
            labelRowNum += 1
        
        if showBuyVol
            float y1 = matrixTop - (labelRowNum * rowHeight)
            float y2 = y1 - rowHeight
            box.new(labelLeft, y1, labelRight, y2, bgcolor=color.new(bullColorBright, 70), border_color=bullColorBright, border_width=1, text="Buy Vol", text_color=color.white, text_size=size.small, text_halign=text.align_center, text_valign=text.align_center)
            labelRowNum += 1
        
        if showSellVol
            float y1 = matrixTop - (labelRowNum * rowHeight)
            float y2 = y1 - rowHeight
            box.new(labelLeft, y1, labelRight, y2, bgcolor=color.new(bearColorBright, 70), border_color=bearColorBright, border_width=1, text="Sell Vol", text_color=color.white, text_size=size.small, text_halign=text.align_center, text_valign=text.align_center)
            labelRowNum += 1

// ─────────────────────────────────────────────────────────────────────────────
// NEXURAL FLOW METER
// ─────────────────────────────────────────────────────────────────────────────

var table meterTable = table.new(getMeterPosition(), 2, 10, bgcolor=color.new(#0d1117, 5), border_width=1, border_color=color.new(nexuralAccent, 50))

if showMeter
    float buyPct = totalVolume > 0 ? buyVol / totalVolume * 100 : 50
    float sellPct = totalVolume > 0 ? sellVol / totalVolume * 100 : 50
    
    string biasText = delta > 0 ? "BUYERS" : delta < 0 ? "SELLERS" : "NEUTRAL"
    color biasColor = delta > 0 ? bullColorBright : delta < 0 ? bearColorBright : lowActivityColor
    
    string intensityText = switch
        absDeltaPct >= 70 => "EXTREME"
        absDeltaPct >= 50 => "STRONG"
        absDeltaPct >= 30 => "MODERATE"
        absDeltaPct >= 15 => "WEAK"
        => "NEUTRAL"
    
    color meterBgColor = absDeltaPct >= activityThreshold ? color.new(biasColor, 40) : color.new(lowActivityColor, 40)
    color headerBg = color.new(nexuralAccent, 70)
    
    // Header - Nexural Flow Branding
    table.cell(meterTable, 0, 0, "⚡ NEXURAL FLOW", text_color=nexuralAccent, text_size=getMeterTextSize(), bgcolor=headerBg, text_font_family=font.family_monospace)
    table.cell(meterTable, 1, 0, biasText, text_color=biasColor, text_size=getMeterTextSize(), bgcolor=headerBg, text_font_family=font.family_monospace)
    
    // Intensity Row
    table.cell(meterTable, 0, 1, "Intensity", text_color=color.new(color.white, 40), text_size=size.small, text_halign=text.align_right)
    table.cell(meterTable, 1, 1, intensityText, text_color=color.white, text_size=getMeterTextSize(), bgcolor=meterBgColor)
    
    // Imbalance Ratio Row
    string imbalanceLabel = isBuyDominant ? "BUY " + imbalanceStr : "SELL " + imbalanceStr
    color imbalanceColor = isBuyDominant ? bullColorBright : bearColorBright
    table.cell(meterTable, 0, 2, "Imbalance", text_color=color.new(color.white, 40), text_size=size.small, text_halign=text.align_right)
    table.cell(meterTable, 1, 2, imbalanceLabel, text_color=color.white, text_size=getMeterTextSize(), bgcolor=color.new(imbalanceColor, 40))
    
    // Delta
    color deltaColor = absDeltaPct >= activityThreshold ? biasColor : lowActivityColor
    table.cell(meterTable, 0, 3, "Delta", text_color=color.new(color.white, 40), text_size=size.small, text_halign=text.align_right)
    table.cell(meterTable, 1, 3, formatVol(delta), text_color=color.white, text_size=getMeterTextSize(), bgcolor=color.new(deltaColor, 40))
    
    // Delta %
    table.cell(meterTable, 0, 4, "Delta %", text_color=color.new(color.white, 40), text_size=size.small, text_halign=text.align_right)
    table.cell(meterTable, 1, 4, formatPct(deltaPct), text_color=color.white, text_size=getMeterTextSize(), bgcolor=color.new(deltaColor, 30))
    
    // Buy Volume
    table.cell(meterTable, 0, 5, "Buy Vol", text_color=bullColorBright, text_size=size.small, text_halign=text.align_right)
    table.cell(meterTable, 1, 5, formatVol(buyVol) + " (" + str.tostring(buyPct, "#.#") + "%)", text_color=color.white, text_size=getMeterTextSize(), bgcolor=color.new(bullColorBright, 50))
    
    // Sell Volume
    table.cell(meterTable, 0, 6, "Sell Vol", text_color=bearColorBright, text_size=size.small, text_halign=text.align_right)
    table.cell(meterTable, 1, 6, formatVol(sellVol) + " (" + str.tostring(sellPct, "#.#") + "%)", text_color=color.white, text_size=getMeterTextSize(), bgcolor=color.new(bearColorBright, 50))
    
    // Volume
    table.cell(meterTable, 0, 7, "Volume", text_color=color.new(color.white, 40), text_size=size.small, text_halign=text.align_right)
    table.cell(meterTable, 1, 7, formatVol(totalVolume), text_color=color.white, text_size=getMeterTextSize(), bgcolor=color.new(#546e7a, 50))
    
    // Bar VWAP
    table.cell(meterTable, 0, 8, "Bar VWAP", text_color=nexuralAccent, text_size=size.small, text_halign=text.align_right)
    table.cell(meterTable, 1, 8, formatPrice(barVWAP), text_color=color.white, text_size=getMeterTextSize(), bgcolor=color.new(nexuralAccent, 60))
    
    // LTF Info
    table.cell(meterTable, 0, 9, "LTF", text_color=color.new(color.white, 60), text_size=size.tiny, text_halign=text.align_right)
    table.cell(meterTable, 1, 9, lowerTimeframe, text_color=color.new(color.white, 40), text_size=size.tiny, bgcolor=color.new(#363a45, 70))

// ─────────────────────────────────────────────────────────────────────────────
// VOLUME CHECK
// ─────────────────────────────────────────────────────────────────────────────

var float cumVol = 0.0
cumVol += nz(volume)

if barstate.islast and cumVol == 0
    runtime.error("No volume data available for this symbol.")

Overview

Nexural OrderFlow Matrix calculates volume metrics using lower timeframe volume delta data, displaying per-candle metrics such as Delta, Delta percentage, Buy/Sell volume, Bar VWAP, and Cumulative Volume Delta. Users can customize lower timeframe modes, display settings, activity thresholds, and CVD reset frequencies. Lower timeframe metrics depend on available intrabar data granularity.

Details

Published by

JasonTeixeira on GitHub

Code credit

Nexural Trading, as written in the script's header

Type

Indicator, Pine Script v6

Draws

Separate pane below the chart

Category

Volume, Screeners & dashboards

Markets

Any symbol

Timeframes

M1-M5, M15-H1

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Topics

algorithmic-tradingbacktestingfuturesmcpninjatraderninjatrader8quantitative-financeautomation-engineeringninjascriptplayback

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Timeframe ModestringAutoltfMode
Custom Timeframetimeframe1customTF
Show Matrix TablebooltrueshowMatrix
Show Imbalance BarsbooltrueshowImbalanceBars
Text SizestringTinytextSizeInput
Show Row LabelsbooltrueshowRowLabels
Row Heightfloat1.0rowHeight
Activity Threshold %float25.0activityThreshold
Bar Heightfloat3.0imbalanceBarHeight
Show Volume LabelsbooltrueshowImbalanceLabels
Show PercentagebooltrueshowImbalancePct
VolumebooltrueshowVolume
Show all 30 settings
SettingTypeDefaultVariable
Bar VWAPbooltrueshowBarVWAP
DeltabooltrueshowDelta
Delta %booltrueshowDeltaPct
Max ΔboolfalseshowMaxDelta
Min ΔboolfalseshowMinDelta
Bar Δ CVDbooltrueshowBarCVD
Buy VolbooltrueshowBuyVol
Sell VolbooltrueshowSellVol
Show Nexural Flow MeterbooltrueshowMeter
Meter SizestringNormalmeterSize
Meter PositionstringTop RightmeterPos
CVD ResetstringDailycvdResetInput
Bullish (Strong)color#00e676bullColorBright
Bearish (Strong)color#ff1744bearColorBright
Low Activitycolor#3d4450lowActivityColor
Nexural Accentcolor#00b8d4nexuralAccent
Volume (High)color#ffab00volumeColorHigh
Volume (Low)color#4a4530volumeColorLow
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

Oscillator Suite

by TamaraKGreen
46 stars

Oscillator Suite plots a normalised price oscillator in a separate pane and overlays a signal line that can use SMA, EMA, WMA, HMA, RMA, VWMA, T3, ZEMA, KAMA, or GKEMA. It marks bullish and bearish divergences, a smoothed money-flow series, confluence areas an

Indicator v5 Oscillators & momentumDivergence
Updated 7 weeks ago · None stated GitHub repository of Oscillator Suite

Relative Strength Table

by ChartsLector
41 stars

This indicator builds a table of relative strength for up to six user-chosen symbols against a benchmark, defaulting to SPY. It measures strength over four lookback periods, can average the visible periods, and can add relative volume as current volume divided

Indicator v6 Screeners & dashboardsVolume
Updated 2 days ago · None stated GitHub repository of Relative Strength Table

This indicator calculates the Relative Strength Index (RSI) alongside a simple moving average to generate directional momentum signals in a separate pane. It supports Break Flip and Break Continuous scanning modes for long and short setups. A wide array of opt

Indicator v5 Oscillators & momentumVolatility & bands
Updated 1 year ago · None stated GitHub repository of Momentum Setup: RSI Direction Confirmation
11 stars

This indicator plots a smoothed Z-score of cumulative volume delta in a separate pane, showing whether buying or selling pressure is dominant and when the reading enters extreme zones. It marks spot accumulation, climax or exhaustion, and pivot-based price-vol

Indicator v6 Oscillators & momentumVolume Repaints
Updated 7 weeks ago · MIT GitHub repository of CVD Z-Score [NeuNue]

The Candle Pressure Index measures buying versus selling pressure from candle geometry and relative volume. Each bar combines close location, body ratio, and volume rank into a raw pressure value. An exponential moving average of that pressure forms the CPI os

Indicator v6 Oscillators & momentumVolume
Updated yesterday · MIT GitHub repository of Candle Pressure Index [WavesUnchained]
7 stars

Arbitrage Detector [LuxAlgo] compares price and volume data across multiple crypto exchanges or forex brokers against the charted asset. It calculates cross-venue spreads and measures their percentile ranks to highlight market anomalies, plotting a smoothed gr

Indicator v6 Screeners & dashboardsVolume
Updated 3 months ago · None stated GitHub repository of Arbitrage Detector [LuxAlgo]

More indicators

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers