Strategy · Pine Script v6 · On the chart

DeltaFlow Volume Profile Strategy

by rosijay17-cmd

A strategy that builds a volume profile with delta over a lookback window and trades touches of its point of control and value area high and low levels, long or short.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code248
Settings18inputs
LicenceGPL-3.0
Last update7 days ago22 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 strategy, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart. The trades and results appear in the Strategy Tester tab; adjust the settings with the gear icon.

Source Code

248 lines of Pine Script v6 from DeltaFlow_Volume_Profile_Strategy.pine, published under GPL-3.0. Keep the author's credit and licence lines when you reuse it.

DeltaFlow_Volume_Profile_Strategy.pine
//@version=6
// NOTE: strategy() declaration parameters (initial_capital, default_qty_value,
// commission_value) require a compile-time "const float" — an input.*() call
// resolves to "input float", which the compiler rejects here (CE10123). These
// three are therefore fixed constants below; TradingView's own Properties tab
// already exposes Initial Capital and Commission for the user to change
// without touching the script. Position size stays genuinely input-driven —
// see positionSizePctInput below — by computing an explicit qty at entry
// time instead of relying on the declaration's default_qty_value.
strategy(title = "DeltaFlow Volume Profile Strategy", shorttitle = "DeltaFlow VP Strategy", overlay = true, max_boxes_count = 500, max_lines_count = 500, max_labels_count = 500, initial_capital = 50000.0, currency = currency.USD, default_qty_type = strategy.cash, default_qty_value = 50000.0, commission_type = strategy.commission.percent, commission_value = 0.02, process_orders_on_close = true, calc_on_every_tick = false)

// ============================================================================
// VOLUME PROFILE INPUTS — preserved verbatim from the DeltaFlow reference
// (same names, same defaults, same missing group/title where the original
// left them ungrouped) for exact render parity.
// ============================================================================
lookBack     = input.int(200, "LookBack")
binsAmount   = input.int(30, "Bins", maxval = 100, minval = 10)
offset       = input.int(5)

deltaHeatMap = input.bool(true, "Delta Heat Map", group = "Features")
deltaDisplay = input.bool(true, "Delta", group = "Features")
volumeBars   = input.bool(true, "Volume Bars", group = "Features")
pocDisplay   = input.bool(true, "", inline = "poc", group = "Features")
pocColor     = input.color(color.rgb(0, 183, 255), "PoC Color", inline = "poc", group = "Features")

bullcolor    = input.color(color.teal, "Volume +/-", inline = "vol")
bearcolor    = input.color(color.rgb(230, 150, 30), "", inline = "vol")

// ============================================================================
// STRATEGY INPUTS (Phase 2)
// ============================================================================
const string G_STRAT = "Strategy"
positionSizePctInput = input.float(10.0, "Position Size (% of Equity)", minval = 1.0, maxval = 100.0, group = G_STRAT)
enableLongInput      = input.bool(true, "Enable Long Trades", group = G_STRAT)
enableShortInput     = input.bool(true, "Enable Short Trades", group = G_STRAT)
toleranceTicksInput  = input.int(2, "Level Touch Tolerance (ticks)", minval = 0, group = G_STRAT)
valueAreaPctInput    = input.float(70.0, "Value Area %", minval = 50.0, maxval = 95.0, group = G_STRAT)
rMultipleInput       = input.float(2.0, "Target R-Multiple", minval = 0.5, group = G_STRAT)
showLevelsInput      = input.bool(true, "Plot POC / VAH / VAL Signal Levels", group = G_STRAT)
showEntryMarkersInput = input.bool(true, "Plot Entry Markers", group = G_STRAT)

type vp_
    array<float> volumeArry
    array<float> bearVolume
    array<float> bullVolume

vp = vp_.new(array.new<float>(binsAmount, 0.), array.new<float>(binsAmount, 0.), array.new<float>(binsAmount, 0.))

MaxMin     = array.new<float>()
var boxes  = array.new<box>()

// ============================================================================
// PHASE 2 — SIGNAL-PATH VOLUME PROFILE (non-repainting)
// Computed every confirmed bar from the window [1, lookBack] — i.e. shifted
// one full bar back from the display profile below — so the level a signal
// reacts to on bar N was already fixed before bar N started forming. This
// is deliberately a *different* calculation from the display block below;
// see the deviations note in the accompanying change log.
// ============================================================================
f_signalProfile(int bars, int bins) =>
    float sigTop = high[1]
    float sigBot = low[1]
    for i = 1 to bars
        sigTop := math.max(sigTop, high[i])
        sigBot := math.min(sigBot, low[i])
    float sigStep = (sigTop - sigBot) / bins
    array<float> sigVol = array.new<float>(bins, 0.0)
    for i = 1 to bars
        float price = close[i]
        for k = 0 to bins - 1
            float lower = sigBot + sigStep * k
            float mid   = lower + sigStep / 2
            if math.abs(mid - price) <= sigStep
                array.set(sigVol, k, array.get(sigVol, k) + volume[i])
    int   pocIdx = 0
    float pocVol = 0.0
    for k = 0 to bins - 1
        float v = array.get(sigVol, k)
        if v > pocVol
            pocVol := v
            pocIdx := k
    float sigPoc = sigBot + sigStep * pocIdx + sigStep / 2
    float totalVol = array.sum(sigVol)
    float target = totalVol * (valueAreaPctInput / 100.0)
    float cum = array.get(sigVol, pocIdx)
    int lo = pocIdx
    int hi = pocIdx
    while cum < target and (lo > 0 or hi < bins - 1)
        float volBelow = lo > 0 ? array.get(sigVol, lo - 1) : -1.0
        float volAbove = hi < bins - 1 ? array.get(sigVol, hi + 1) : -1.0
        if volAbove >= volBelow
            hi += 1
            cum += array.get(sigVol, hi)
        else
            lo -= 1
            cum += array.get(sigVol, lo)
    float sigVah = sigBot + sigStep * (hi + 1)
    float sigVal = sigBot + sigStep * lo
    [sigTop, sigBot, sigPoc, sigVah, sigVal]

bool enoughHistory = bar_index >= lookBack + 1

var float sigTop = na
var float sigBot = na
var float sigPocPrice = na
var float sigVahPrice = na
var float sigValPrice = na

if enoughHistory
    [profTop, profBot, profPoc, profVah, profVal] = f_signalProfile(lookBack, binsAmount)
    sigTop := profTop
    sigBot := profBot
    sigPocPrice := profPoc
    sigVahPrice := profVah
    sigValPrice := profVal

float tick = syminfo.mintick
float tol  = toleranceTicksInput * tick

bool longVpocReclaim     = enoughHistory and ta.crossover(close, sigPocPrice)
bool longSupportBounce   = enoughHistory and low <= sigValPrice + tol and close > sigValPrice
bool longCondition       = enableLongInput and (longVpocReclaim or longSupportBounce)

bool shortVpocReject     = enoughHistory and ta.crossunder(close, sigPocPrice)
bool shortResistanceFail = enoughHistory and high >= sigVahPrice - tol and close < sigVahPrice
bool shortCondition      = enableShortInput and (shortVpocReject or shortResistanceFail)

var float longStopPrice  = na
var float longTargetPrice = na
var float shortStopPrice = na
var float shortTargetPrice = na

float orderQty = close > 0 ? strategy.equity * (positionSizePctInput / 100.0) / close : na

if longCondition and strategy.position_size <= 0
    strategy.entry("Long", strategy.long, qty = orderQty)
    longStopPrice := sigBot
    float longRisk = close - sigBot
    longTargetPrice := close + longRisk * rMultipleInput

if shortCondition and strategy.position_size >= 0
    strategy.entry("Short", strategy.short, qty = orderQty)
    shortStopPrice := sigTop
    float shortRisk = sigTop - close
    shortTargetPrice := close - shortRisk * rMultipleInput

if strategy.position_size > 0
    strategy.exit("Long Exit", from_entry = "Long", stop = longStopPrice, limit = longTargetPrice)
if strategy.position_size < 0
    strategy.exit("Short Exit", from_entry = "Short", stop = shortStopPrice, limit = shortTargetPrice)

plot(showLevelsInput and enoughHistory ? sigPocPrice : na, "Signal POC", color = color.new(pocColor, 0), linewidth = 1, style = plot.style_linebr)
plot(showLevelsInput and enoughHistory ? sigVahPrice : na, "Signal VAH", color = color.new(color.red, 0), linewidth = 1, style = plot.style_linebr)
plot(showLevelsInput and enoughHistory ? sigValPrice : na, "Signal VAL", color = color.new(color.green, 0), linewidth = 1, style = plot.style_linebr)

plotshape(showEntryMarkersInput and longCondition and strategy.position_size[1] <= 0 and strategy.position_size > 0 ? low : na, "Long Entry", style = shape.triangleup, location = location.belowbar, color = color.new(color.lime, 0), size = size.small)
plotshape(showEntryMarkersInput and shortCondition and strategy.position_size[1] >= 0 and strategy.position_size < 0 ? high : na, "Short Entry", style = shape.triangledown, location = location.abovebar, color = color.new(color.red, 0), size = size.small)

// ============================================================================
// PHASE 1 — DISPLAY VOLUME PROFILE (verbatim from the DeltaFlow reference)
// Recomputed only on the last bar, using the window [0, lookBack] (current
// forming bar included), exactly matching the original indicator's math and
// drawing order for visual parity. This is intentionally NOT the same window
// as the signal profile above.
// ============================================================================
if barstate.islast

    if boxes.size() > 0
        for b in boxes
            b.delete()
        boxes.clear()

    for i = 0 to lookBack
        MaxMin.push(high[i])
        MaxMin.push(low[i])

    top = MaxMin.max()
    bot = MaxMin.min()
    step = (top-bot)/binsAmount

    for i = 0 to lookBack

        price = close[i]
        isBear = close[i] < open[i]
        voll = volume[i]

        for k = 0 to binsAmount - 1
            lower = bot + step * k
            mid   = lower + step/2

            if math.abs(mid - price) <= step
                vp.volumeArry.set(k, vp.volumeArry.get(k) + voll)

                if isBear
                    vp.bearVolume.set(k, vp.bearVolume.get(k) + voll)
                else
                    vp.bullVolume.set(k, vp.bullVolume.get(k) + voll)

    for i = 0 to binsAmount - 1

        start = bar_index + 100+offset

        volumeArryvalue = vp.volumeArry.get(i)

        lower = bot + step * i
        upper = lower + step
        mid   = lower + step /2
        vol   = int(vp.volumeArry.get(i) / vp.volumeArry.max() * 100)

        bullV = math.floor(vp.bullVolume.get(i) / vp.volumeArry.max() * 100)
        bearV = math.floor(vp.bearVolume.get(i) / vp.volumeArry.max() * 100)

        size  = (start - start-vol)

        bullsPercent = math.abs(bullV/size*100)
        bearsPercent = math.abs(bearV/size*100)

        bullsPercent := bullsPercent > 100 ? 100 : bullsPercent

        delta       = bullsPercent - bearsPercent
        deltaColor  = color.from_gradient(delta, -30, 30, bearcolor, bullcolor)

        box poc      = na
        box labelBox = na
        box MapBody  = na
        box bulls    = na
        box bears    = na

        if deltaHeatMap
            MapBody  := box.new(start-lookBack-50-vol, upper, start, lower, border_color = chart.bg_color, border_width = 0, bgcolor = color.from_gradient(vol, 0, 100, color.new(deltaColor, 100), color.new(deltaColor, 70)))
        if vol == 100 and pocDisplay
            poc := box.new(start-lookBack-50-vol, upper, start, lower, border_color = pocColor, border_width = 1, bgcolor = na, text = str.tostring(volumeArryvalue, format.volume), text_color = chart.fg_color)
        if deltaDisplay
            labelBox := box.new(start+15, upper, start, lower, border_color = chart.bg_color, border_width = 1, bgcolor = color.new(deltaColor, 80), text = "Δ " + str.tostring(delta, format.percent), text_color = deltaColor)

        body        = box.new(start-vol, upper, start, lower, border_color = chart.bg_color, border_width = 1, bgcolor = color.new(deltaColor, 50))

        if volumeBars
            bulls  := box.new(start-bullV, mid, start, lower, bgcolor = bullcolor, border_color = chart.bg_color, border_width = 1, text = str.tostring(bullsPercent, format = format.percent), text_halign = text.align_right)
            bears  := box.new(start-bearV, upper, start, mid, bgcolor = bearcolor, border_color = chart.bg_color, border_width = 1, text = str.tostring(bearsPercent, format = format.percent), text_halign = text.align_right)

        boxes.push(poc)
        boxes.push(labelBox)
        boxes.push(MapBody)
        boxes.push(body)
        boxes.push(bulls)
        boxes.push(bears)

Overview

The window, bin count, value area percentage and touch tolerance in ticks are adjustable. Position size is a percentage of equity and the target is a multiple of the risk. It draws the profile bars, delta heat map, signal levels and entry markers on the price chart.

Details

Published by

rosijay17-cmd on GitHub

Type

Strategy, Pine Script v6

Draws

On the price chart

Category

Volume, Support & resistance

Markets

Any symbol

Timeframes

Any timeframe

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.

Settings

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

SettingTypeDefaultVariable
LookBackint200lookBack
Binsint30binsAmount
offsetint5offset
Delta Heat MapbooltruedeltaHeatMap
DeltabooltruedeltaDisplay
Volume BarsbooltruevolumeBars
pocDisplaybooltruepocDisplay
PoC Colorcolorcolor.rgb(0, 183, 255)pocColor
Volume +/-colorcolor.tealbullcolor
bearcolorcolorcolor.rgb(230, 150, 30)bearcolor
Position Size (% of Equity)float10.0positionSizePctInput
Enable Long TradesbooltrueenableLongInput
Show all 18 settings
SettingTypeDefaultVariable
Enable Short TradesbooltrueenableShortInput
Level Touch Tolerance (ticks)int2toleranceTicksInput
Value Area %float70.0valueAreaPctInput
Target R-Multiplefloat2.0rMultipleInput
Plot POC / VAH / VAL Signal LevelsbooltrueshowLevelsInput
Plot Entry MarkersbooltrueshowEntryMarkersInput
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

257 stars

This overlay strategy is built for ES futures on the one-minute chart. It plots a volume-weighted moving average of price opens and standard-deviation bands at Fibonacci ratios, plus a second longer volume-weighted average from a higher-timeframe open. Call an

Strategy v5 Volatility & bandsMoving averages
Updated 6 weeks ago · None stated GitHub repository of ES Futures 1M No Repaint
7 stars

Calculates volume profile levels over a lookback window to identify support, resistance, and Point of Control (POC) lines on the price chart. It executes trades based on price interaction with these low-volume zones, featuring customizable signal inversion and

Strategy v6 ScalpingVolume
Updated 1 year ago · None stated GitHub repository of Enhanced NQ1 Scalping Strategy

Wyckoff Phase

by muammeryldrm42
7 stars

This strategy identifies Wyckoff consolidation ranges directly on the price chart to trade potential spring and upthrust events. It calculates highest highs and lowest lows over a customizable lookback period, filtering setups by average volume spikes and ATR

Strategy v5 SMC / ICT / price actionSupport & resistance
Updated 3 months ago · MIT GitHub repository of Wyckoff Phase

This strategy combines volume surge detection, Fibonacci retracements, moving averages, and ATR volatility for trade execution. Long positions trigger when price exceeds the 0.618 Fibonacci level, price stays above a 200-period SMA, a fast EMA crosses above a

Strategy v5 TrendMoving averages
Updated 1 year ago · MIT GitHub repository of Optimized Volume + Fibonacci + Trend + ATR Strategy
3 stars

Psychological Levels is a price-chart strategy that draws quarter, half, and whole rounded price levels. A rounding value sets the level spacing, and each level type can be toggled with its own color, line style, and width. Buy and sell volume thresholds, a pr

Strategy v5 Support & resistanceVolume
Updated 5 months ago · None stated GitHub repository of Psychological Levels

The Judas Indicator

by regardhodler
3 stars

The Judas Indicator strategy calculates a multi-factor composite score combining Volume Profile High Volume Nodes, Cumulative Volume Delta (CVD), pivot proximity, volume absorption, order imbalance, and higher-timeframe trend EMAs. It triggers trade entries wh

Strategy v5 TrendVolume
Updated 8 months ago · None stated GitHub repository of The Judas Indicator

More strategys

Trade Your Charts With a Regulated Broker

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

Compare brokers