ml_vsa is a dependency-free library for Pine v6 that packages the classic Volume Spread Analysis reading of a bar into one shared vocabulary. Most studies describe absorption vaguely — “price made a high but the oscillator did not.” Import one shared implementation and a script can instead say “Upthrust” or “Stopping Volume” — a named, directional event with a fixed definition — so “the same event” means the same thing across every script you build.

The idea

VSA reads each bar as EFFORT (volume) versus RESULT (the spread, and where the bar closed inside its range):

Effort with no result — heavy volume, narrow spread — is absorption: someone is soaking up orders without moving price.
Result with no effort — wide spread, light volume — is a move with nothing behind it.
A new extreme that gets rejected on volume — pushes past the prior high/low but closes back inside — is a trap (Upthrust up, Shakeout down).

Each function takes a series source (high, low, close, volume) and simple window lengths, so it drops into any study. Percentile thresholds follow standard VSA practice and are baked in; the windows are yours.

Primitives
closePos(h, l, c) — where the bar closed inside its range: 0 = on the low, 1 = on the high.
spreadPct(h, l, len) — the current bar’s range as a percentile (0..100) of its own recent history. The RESULT axis: is this a wide bar or a narrow one, for this symbol right now.
volPct(v, len) — the current bar’s volume as a percentile (0..100) of its own history. The EFFORT axis. On a volumeless symbol this is flat and the volume-gated events simply never fire.
Named events (one-bar classifications; each self-contained, each returns a bool unless noted)
noDemand(h,l,c,v,len) — bearish. An up-bar on NARROW spread and LOW volume: the rally has no effort behind it.
noSupply(h,l,c,v,len) — bullish. A down-bar on narrow spread and low volume: no selling pressure left.
upthrust(h,l,c,v,len,pivLen) — bearish. Pushes to a NEW HIGH (over the prior pivLen highs) on HIGH volume but closes back near the LOW — buyers trapped.
shakeout(h,l,c,v,len,pivLen) — bullish. Pushes to a NEW LOW on high volume but closes back near the HIGH — sellers trapped (a Spring).
stoppingVolume(h,l,c,v,len) — bullish. A WIDE down-bar on VERY HIGH volume that closes OFF the low — heavy demand stepping in to halt a decline.
climax(h,l,c,v,len) — returns +1 / −1 / 0. CLIMACTIC volume (≥90th pct) on a wide bar: an up-climax is a potential buying-climax exhaustion (returns −1, bearish); a down-climax is a selling-climax exhaustion (returns +1, bullish).
effortNoResult(h,l,v,len) — a NON-directional absorption flag. High volume, narrow spread: effort with no result. Where the market is soaking up orders; direction needs context.
Composites
vsaBias(h,l,c,v,len,pivLen) — the events netted to a direction: +1 bullish, −1 bearish, 0 none/conflict. (The non-directional absorption flag is deliberately excluded.) Use this one call so a “VSA-confirmed” read means the same thing on every engine.
vsaCode(h,l,c,v,len,pivLen) — an integer identifying WHICH event dominates (priority: climax > trap > stopping > no-demand/supply > absorption): 3 buying-climax · −3 selling-climax · 2 upthrust · −2 shakeout · −1 stopping · 4 no-demand · −4 no-supply · 5 absorption · 0 none. (The sign here identifies the event, not the trade direction — use vsaBias for direction.)
vsaLabel(h,l,c,v,len,pivLen) — the dominant event as a string (“Upthrust”, “Stopping volume”, …) for a dashboard or a marker.
How to use

See also  Elder SafeZone Stop | Trading Indicator

Mark the events, and read a shared direction:

//version=6
indicator(“Example — VSA events”, overlay = true)
import Market_Logic_India/ml_vsa/1 as vsa

len = input.int(50, “VSA history window”)
piv = input.int(5, “New-extreme lookback”)

ut = vsa.upthrust(high, low, close, volume, len, piv)
so = vsa.shakeout(high, low, close, volume, len, piv)
sv = vsa.stoppingVolume(high, low, close, volume, len)

plotshape(ut, “Upthrust”, shape.triangledown, location.abovebar, color.red, text = “UT”)
plotshape(so, “Shakeout”, shape.triangleup, location.belowbar, color.green, text = “SO”)
plotshape(sv, “Stopping”, shape.square, location.belowbar, color.teal, text = “SV”)

bias = vsa.vsaBias(high, low, close, volume, len, piv) // +1 / -1 / 0
bgcolor(bias > 0 ? color.new(color.green, 90) : bias < 0 ? color.new(color.red, 90) : na)

The events pair naturally with level and flow tools: an Upthrust into a resistance level, or Stopping Volume on a support level, is far stronger than either read alone.

Notes
Non-repainting: every read is a pure function of closed-bar spread, volume, close and their rolling history (ta.percentrank / ta.highest / ta.lowest). Nothing looks ahead. To be certain a live bar’s event never flickers, gate on barstate.isconfirmed in your host script.
State safety: the composites call each event UNCONDITIONALLY and then select, so the ta.* inside every event runs on every bar (the correct Pine pattern). If you call the individual events yourself, keep them out of if/ternary branches for the same reason.
Types: pass series for the price/volume inputs and simple int for the window lengths.
These are OHLCV-based proxies for the classic tape reads, not exchange-grade order flow — pair every event with a forward test (e.g. ml_calib) before trusting its edge on your instrument.
Concept credits

Volume Spread Analysis and the effort-vs-result principle — with the named events No Demand, No Supply, Upthrust, Shakeout/Spring, Stopping Volume, Buying/Selling Climax and Test — descend from Richard D. Wyckoff and the VSA tradition associated with Tom Williams. This library is an original, dependency-free Pine v6 packaging of those public techniques; it is not affiliated with, nor endorsed by, any originator.

See also  Volatility Signature Plot | Trading Indicator

License

Mozilla Public License 2.0 — as required for TradingView libraries (open source). Free to import and build on.


Source link

Author

Shin John
Shin JohnYtv Market News
Share-market news writer and analyst with deep experience covering equities, commodities, forex, and cryptocurrencies for readers in the USA, UK, Canada, and Australia. Ytv Market News delivers timely market updates, practical trading insights, and clear explanations of macro and company-level catalysts that move prices. Combines on-the-ground financial reporting with technical analysis, using concise charts and actionable ideas to help investors and traders make smarter decisions.