Indicator · Pine Script v5 · On the chart

Volume Spikes & Growing Volume Signals With Alerts

by ivansoft· code credited to FriendOfTheTrend

This indicator marks volume spikes and growing-volume conditions on the price chart.

View on GitHub

GitHub stars1on the repository
Pine versionv5runs as is
Lines of code182
Settings8inputs
LicenceNone statedfile: MPL-2.0
Last update1 year ago1 Mar 2025

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

182 lines of Pine Script v5 from examples/202405/volume_spike_dmi.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

volume_spike_dmi.pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © FriendOfTheTrend

//@version=5
indicator("Volume Spikes & Growing Volume Signals With Alerts & Scanner", shorttitle="Volume Spike Scanner", overlay=true)

//Inputs
//info = input.bool(false, title="This indicator takes a while to load because it has to pull data and calculations from 8 other tickers, so please be patient when you load it on a chart. This indicator calculates volume spikes and growing volume. The top inputs are controlling the numbers used to calculate volume spikes which is using only 1 bar of volume data to catch these spikes. The second input section has the numbers used for calculations for when volume is growing over a certain amount of bars compared to the overall average. Read the tooltips for more clarification. You will need to adjust these settings on different charts as some tickers will have larger or smaller volume spikes and medians.", confirm=true)
spikeMultiple = input.int(3, title="Volume Spike Amount", tooltip="If volume spikes by this amount, an arrow will be shown. Ex: if set to 3, the volume will need to spike to a level that is 3 times the amount of the median of the last 100 bars or whatever amount of bars you set in the next input.", group="Volume Spike")
barsBack = input.int(1000, title="How Many Bars Back To Calculate The Median From", tooltip="This number is the amount of bars back you want the median to be calculated from. So if it is set to 100, the indicator will calculate the median or average of the last 100 bars. The number calculated is the median and will determine what level needs to be hit to achieve a Volume Spike, multiplied by the amount set in the first input.", group="Volume Spike")
medianLengthCurrent = input.int(5, title="Number Of Bars To Caluclate Current Volume Median", tooltip="This number is used to calculate the current median of volume for the last few bars. If you put 5 in here, then this will use the 5 most recent bars of data to calculate the current median volume which will be used to look for growing volume trends using the next two inputs.", group="Volume Growing")
spikeMultipleCurrent = input.int(3, title="Volume Spike Amount For Current Median", tooltip="This is a multplier for the median of the current volume trend. If 5 bars were used from the previous input, then the volume median over the last 5 bars will need to be greater than the median multiplied by this number. So if the median is 300 and this input is set to 3, volume median will need to reach 900 for it to give a signal.", group="Volume Growing")
barsBackCurrent = input.int(1000, title="Number Of Bars Back To Calculate Overall Median", tooltip="This value corresponds to the number of bars back to be used to calculate the current volume median. If you enter 1000 here, it will calculate the avergae volume over the last 1000 bars and use this as a benchmark to calculate growing volume or volume spikes.", group="Volume Growing")
maLength = input.int(20, title="Volume Moving Average Length", tooltip="If the volume moving average is increasing for 3 bars consecutively, then the indicator will give a signal. The moving average length chosen here will detemine how long of a volume moving average you are using for this calculation.", group="Volume Growing")

//DMI Input Controls
dilength = input.int(1, title="DMI Length", group="Buy & Sell Pressure")
smoothing = input.int(1, title="DMI Smoothing", group="Buy & Sell Pressure")


//Color
volBuildColor = #00e67610
green = #00e67610
red = #ff525210

//DMI
[plus, minus, adx] = ta.dmi(dilength, smoothing)

if plus > minus
    volBuildColor := green
else
    volBuildColor := red

//Volume Spikes
vol = ta.median(volume, barsBack)
volCurrent = ta.median(volume, barsBackCurrent)
upSpike = false
downSpike = false

if volume > vol*spikeMultiple and plus > minus
    upSpike := true
else if volume > vol*spikeMultiple and minus > plus
    downSpike := true

plotchar(upSpike, title="Volume Up Spike Marker", char="🠕", location=location.belowbar, color=color.lime, size=size.small)
plotchar(downSpike, title="Volume Down Spike Marker", char="🠗", location=location.abovebar, color=color.red, size=size.small)

//Volume Increasing
volBuild = false
currentMedian = ta.median(volume, medianLengthCurrent)
volLine = ta.sma(volume, maLength)
maUp = false

if currentMedian > volCurrent*spikeMultipleCurrent or volLine > volLine[1] and volLine[1] > volLine[2] and volLine[2] > volLine[3]
    volBuild := true

bgcolor(volBuild ? volBuildColor : na)





//Ticker 1
// ticker1 = input.symbol("COINBASE:BTCUSD", title="Ticker #1", group="Tickers To Scan")
// ticker2 = input.symbol("COINBASE:ETHUSD", title="Ticker #2", group="Tickers To Scan")
// ticker3 = input.symbol("COINBASE:AVAXUSD", title="Ticker #3", group="Tickers To Scan")
// ticker4 = input.symbol("COINBASE:ADAUSD", title="Ticker #4", group="Tickers To Scan")
// ticker5 = input.symbol("COINBASE:SOLUSD", title="Ticker #5", group="Tickers To Scan")
// ticker6 = input.symbol("COINBASE:DOTUSD", title="Ticker #6", group="Tickers To Scan")
// ticker7 = input.symbol("COINBASE:LTCUSD", title="Ticker #7", group="Tickers To Scan")
// ticker8 = input.symbol("COINBASE:LINKUSD", title="Ticker #8", group="Tickers To Scan")

// //Ticker #1
// ticker1upspike = request.security(ticker1, "", volume > vol*spikeMultiple and plus > minus)
// ticker1downspike = request.security(ticker1, "", volume > vol*spikeMultiple and minus > plus)
// ticker1volbuild = request.security(ticker1, "", currentMedian > volCurrent*spikeMultipleCurrent or volLine > volLine[1] and volLine[1] > volLine[2] and volLine[2] > volLine[3])
// ticker1text = str.tostring(ticker1)

// ticker1bg = color.aqua
// if ticker1upspike or ticker1downspike or ticker1volbuild
//     ticker1bg := color.orange
    
// //Ticker #2
// ticker2upspike = request.security(ticker2, "", volume > vol*spikeMultiple and plus > minus)
// ticker2downspike = request.security(ticker2, "", volume > vol*spikeMultiple and minus > plus)
// ticker2volbuild = request.security(ticker2, "", currentMedian > volCurrent*spikeMultipleCurrent or volLine > volLine[1] and volLine[1] > volLine[2] and volLine[2] > volLine[3])
// ticker2text = str.tostring(ticker2)

// ticker2bg = color.aqua
// if ticker2upspike or ticker2downspike or ticker2volbuild
//     ticker2bg := color.orange
    
// //Ticker #3
// ticker3upspike = request.security(ticker3, "", volume > vol*spikeMultiple and plus > minus)
// ticker3downspike = request.security(ticker3, "", volume > vol*spikeMultiple and minus > plus)
// ticker3volbuild = request.security(ticker3, "", currentMedian > volCurrent*spikeMultipleCurrent or volLine > volLine[1] and volLine[1] > volLine[2] and volLine[2] > volLine[3])
// ticker3text = str.tostring(ticker3)

// ticker3bg = color.aqua
// if ticker3upspike or ticker3downspike or ticker3volbuild
//     ticker3bg := color.orange
    
// //Ticker #4
// ticker4upspike = request.security(ticker4, "", volume > vol*spikeMultiple and plus > minus)
// ticker4downspike = request.security(ticker4, "", volume > vol*spikeMultiple and minus > plus)
// ticker4volbuild = request.security(ticker4, "", currentMedian > volCurrent*spikeMultipleCurrent or volLine > volLine[1] and volLine[1] > volLine[2] and volLine[2] > volLine[3])
// ticker4text = str.tostring(ticker4)

// ticker4bg = color.aqua
// if ticker4upspike or ticker4downspike or ticker4volbuild
//     ticker4bg := color.orange
    
// //Ticker #5
// ticker5upspike = request.security(ticker5, "", volume > vol*spikeMultiple and plus > minus)
// ticker5downspike = request.security(ticker5, "", volume > vol*spikeMultiple and minus > plus)
// ticker5volbuild = request.security(ticker5, "", currentMedian > volCurrent*spikeMultipleCurrent or volLine > volLine[1] and volLine[1] > volLine[2] and volLine[2] > volLine[3])
// ticker5text = str.tostring(ticker5)

// ticker5bg = color.aqua
// if ticker5upspike or ticker5downspike or ticker5volbuild
//     ticker5bg := color.orange
    
// //Ticker #6
// ticker6upspike = request.security(ticker6, "", volume > vol*spikeMultiple and plus > minus)
// ticker6downspike = request.security(ticker6, "", volume > vol*spikeMultiple and minus > plus)
// ticker6volbuild = request.security(ticker6, "", currentMedian > volCurrent*spikeMultipleCurrent or volLine > volLine[1] and volLine[1] > volLine[2] and volLine[2] > volLine[3])
// ticker6text = str.tostring(ticker6)

// ticker6bg = color.aqua
// if ticker6upspike or ticker6downspike or ticker6volbuild
//     ticker6bg := color.orange
    
// //Ticker #7
// ticker7upspike = request.security(ticker7, "", volume > vol*spikeMultiple and plus > minus)
// ticker7downspike = request.security(ticker7, "", volume > vol*spikeMultiple and minus > plus)
// ticker7volbuild = request.security(ticker7, "", currentMedian > volCurrent*spikeMultipleCurrent or volLine > volLine[1] and volLine[1] > volLine[2] and volLine[2] > volLine[3])
// ticker7text = str.tostring(ticker7)

// ticker7bg = color.aqua
// if ticker7upspike or ticker7downspike or ticker7volbuild
//     ticker7bg := color.orange
    
// //Ticker #8
// ticker8upspike = request.security(ticker8, "", volume > vol*spikeMultiple and plus > minus)
// ticker8downspike = request.security(ticker8, "", volume > vol*spikeMultiple and minus > plus)
// ticker8volbuild = request.security(ticker8, "", currentMedian > volCurrent*spikeMultipleCurrent or volLine > volLine[1] and volLine[1] > volLine[2] and volLine[2] > volLine[3])
// ticker8text = str.tostring(ticker8)

// ticker8bg = color.aqua
// if ticker8upspike or ticker8downspike or ticker8volbuild
//     ticker8bg := color.orange


// //Scanner Table Inputs
// tableOn = input.bool(true, title="Turn Table On/Off", group="Table Settings")
// bright = position.bottom_right
// bleft = position.bottom_left
// bcenter = position.bottom_center
// tright = position.top_right
// tleft = position.top_left
// tcenter = position.top_center
// mright = position.middle_right
// mleft = position.middle_left
// mcenter = position.middle_center
// tablePosition = input.string(bcenter, title="Table Position", options=[bright, bleft, bcenter, tright, tleft, tcenter, mright, mleft, mcenter], group="Table Settings")

// //Plot Scanner Table
// dataTable = table.new(tablePosition, columns=8, rows=1, border_color=color.white, border_width=1)
// if tableOn and barstate.islast
//     table.cell(table_id=dataTable, column=0, row=0, text=ticker1text, height=0, text_color=color.white, text_halign=text.align_center, text_valign= text.align_center, bgcolor=ticker1bg)
//     table.cell(table_id=dataTable, column=1, row=0, text=ticker2text, height=0, text_color=color.white, text_halign=text.align_center, text_valign= text.align_center, bgcolor=ticker2bg)
//     table.cell(table_id=dataTable, column=2, row=0, text=ticker3text, height=0, text_color=color.white, text_halign=text.align_center, text_valign= text.align_center, bgcolor=ticker3bg)
//     table.cell(table_id=dataTable, column=3, row=0, text=ticker4text, height=0, text_color=color.white, text_halign=text.align_center, text_valign= text.align_center, bgcolor=ticker4bg)
//     table.cell(table_id=dataTable, column=4, row=0, text=ticker5text, height=0, text_color=color.white, text_halign=text.align_center, text_valign= text.align_center, bgcolor=ticker5bg)
//     table.cell(table_id=dataTable, column=5, row=0, text=ticker6text, height=0, text_color=color.white, text_halign=text.align_center, text_valign= text.align_center, bgcolor=ticker6bg)
//     table.cell(table_id=dataTable, column=6, row=0, text=ticker7text, height=0, text_color=color.white, text_halign=text.align_center, text_valign= text.align_center, bgcolor=ticker7bg)
//     table.cell(table_id=dataTable, column=7, row=0, text=ticker8text, height=0, text_color=color.white, text_halign=text.align_center, text_valign= text.align_center, bgcolor=ticker8bg)

//Alerts
alertcondition(upSpike, title="Bullish Volume Spike Alert", message="Bullish Volume Spike")
alertcondition(downSpike, title="Bearish Volume Spike Alert", message="Bearish Volume Spike")
alertcondition(volBuild, title="Volume Growing Alert", message="Volume Is Growing")

Overview

A spike is flagged when volume reaches a chosen multiple of the median over a selected lookback. Growing volume is flagged when a short recent median exceeds a longer median by another multiple, or when the volume moving average rises for three consecutive bars. DMI length and smoothing settings relate to buy and sell pressure. The title includes alerts and a scanner, and a code note says it loads data from eight other tickers.

Details

Published by

ivansoft on GitHub

Code credit

FriendOfTheTrend, as written in the script's header

Type

Indicator, Pine Script v5

Draws

On the price chart

Category

Volume, Oscillators & momentum, Screeners & dashboards

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.

Topics

pinescripttradingvew

Settings

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

SettingTypeDefaultVariable
Volume Spike Amountint3spikeMultiple
How Many Bars Back To Calculate The Median Fromint1000barsBack
Number Of Bars To Caluclate Current Volume Medianint5medianLengthCurrent
Volume Spike Amount For Current Medianint3spikeMultipleCurrent
Number Of Bars Back To Calculate Overall Medianint1000barsBackCurrent
Volume Moving Average Lengthint20maLength
DMI Lengthint1dilength
DMI Smoothingint1smoothing
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

This overlay indicator screens a pasted list of up to forty symbols and draws a table on the price chart. It classifies bullish or bearish setups from the percent change between the current candle and the candle 250 bars back, then shows RSI with a simple movi

Indicator v5 Oscillators & momentumVolume
Updated 1 year ago · MPL-2.0 GitHub repository of Momentum Setup - Ankush Bajaj Momentum Investing Setup

This overlay indicator builds a horizontal momentum profile over a chosen lookback. It splits price into rows and plots the average WaveTrend of each zone as a bar colored by direction, plus an optional MFI reference band that stays gray when real trade volume

Indicator v6 Oscillators & momentumVolume
Updated yesterday · MIT GitHub repository of Momentum Profile [WavesUnchained]
7 stars

The 7M Multi-Factor Momentum Scoreboard evaluates real-time market momentum across multiple criteria and displays the results in an overlay dashboard panel on the price chart. It tracks anchored percentage price moves based on pre-market, regular open, or post

Indicator v6 Oscillators & momentumVolume
Updated 3 months ago · None stated GitHub repository of 7M Multi-Factor Momentum Scoreboard
4 stars

This indicator overlays an order flow intelligence suite directly on the price chart. It renders a liquidity heatmap across configured price zones, alongside an on-chart information panel displaying volume delta, cumulative volume delta, a momentum compass bas

Indicator v6 VolumeScreeners & dashboards
Updated 2 weeks ago · MIT GitHub repository of GHOST — OrderFlow Intelligence
4 stars

An overlay indicator that calculates multi-timeframe market conditions and displays them in an information panel on the price chart. It evaluates timeframe metrics such as 15-minute and 1-hour periods to monitor RSI values, support and resistance levels, and r

Indicator v5 Screeners & dashboardsOscillators & momentum Repaints
Updated 4 years ago · None stated GitHub repository of SnagProfit Logic 15M 1H
3 stars

CSW MTF Sentiment Line evaluates market sentiment across five customizable timeframes on the price chart. Traded assets can be measured using RSI, volatility (RSI of price standard deviation), or volume (RSI of volume moving average), with values normalized on

Indicator v5 Oscillators & momentumVolatility & bands Repaints
Updated 5 months ago · None stated GitHub repository of CSW MTF Sentiment Line

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