Indicator · Pine Script v6 · Own pane

Volume Historical Patterns

by major

Volume Historical Patterns indicator plots volume analysis in a separate pane.

View on GitHub

GitHub stars2on the repository
Pine versionv6current
Lines of code102
Settings9inputs
LicenceApache-2.0
Last update3 months ago29 Jul 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

102 lines of Pine Script v6 from volume_historical/volume_historical.pine, published under Apache-2.0. Keep the author's credit and licence lines when you reuse it.

volume_historical.pine
// Copyright 2025 Major Hayden
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//@version=6
indicator('Volume Historical Patterns', shorttitle = 'Vol Patterns', format = format.volume, overlay = false)

// User inputs
smaLength = input.int(20, 'SMA Length', minval = 1)
highVolMultiplier = input.float(3.0, 'High Volume Multiplier', minval = 1.0, step = 0.1)
lowVolPercentage = input.float(0.5, 'Low Volume Percentage', minval = 0.1, maxval = 1.0, step = 0.1)

// Time filtering inputs
enableTimeFilter = input.bool(false, 'Enable Time Filter', tooltip = 'Filter volume to specific hours (NYC time). Works on both intraday and daily timeframes.')
startHour = input.int(10, 'Start Hour (NYC)', minval = 0, maxval = 23)
startMinute = input.int(30, 'Start Minute', minval = 0, maxval = 59)
endHour = input.int(15, 'End Hour (NYC)', minval = 0, maxval = 23)
endMinute = input.int(00, 'End Minute', minval = 0, maxval = 59)
showTimeHeadband = input.bool(true, 'Show Time Filter Headband', tooltip = 'Display time filter settings at top of indicator')

// Function to check if a time is within trading hours (NYC time)
isTimeInRange(t) =>
    barHour = hour(t, 'America/New_York')
    barMinute = minute(t, 'America/New_York')

    // Convert times to minutes for easier comparison
    barTimeInMinutes = barHour * 60 + barMinute
    startTimeInMinutes = startHour * 60 + startMinute
    endTimeInMinutes = endHour * 60 + endMinute

    // Check if bar is within the time range
    barTimeInMinutes >= startTimeInMinutes and barTimeInMinutes <= endTimeInMinutes

// Calculate filtered volume based on timeframe
filteredVolume = if not enableTimeFilter
    volume
else if timeframe.isintraday
    // For intraday charts, just check the current bar's time
    nycTime = time('', 'America/New_York')
    isTimeInRange(nycTime) ? volume : 0
else
    // For daily or higher timeframes, sum volume from lower timeframe bars within the time range
    volArray = request.security_lower_tf(syminfo.tickerid, '5', volume)
    timeArray = request.security_lower_tf(syminfo.tickerid, '5', time)

    float totalVol = 0.0
    if array.size(volArray) > 0
        for i = 0 to array.size(volArray) - 1
            barTime = array.get(timeArray, i)
            if isTimeInRange(barTime)
                totalVol += array.get(volArray, i)
    totalVol

// Calculate volume SMA using filtered volume
volumeSMA = ta.sma(filteredVolume, smaLength)

// Track highest volume ever seen (using filtered volume)
var float highestVolume = na
highestVolume := na(highestVolume) ? filteredVolume : math.max(highestVolume, filteredVolume)

// Determine bar color and special condition flags
barColor = color.new(color.white, 75) // Regular bars: white with 25% opacity (75% transparency)
isSpecialBar = false

// Priority order for coloring (most important condition first)
if filteredVolume == highestVolume and filteredVolume > 0
    barColor := color.green // Highest volume ever
    isSpecialBar := true
    barColor
else if filteredVolume >= volumeSMA * highVolMultiplier and volumeSMA > 0
    barColor := color.yellow // High volume (configurable X times SMA)
    isSpecialBar := true
    barColor
else if filteredVolume < volumeSMA * lowVolPercentage and volumeSMA > 0
    barColor := color.red // Low volume (less than 50% of SMA)
    isSpecialBar := true
    barColor

plot(filteredVolume, style = plot.style_columns, color = barColor, linewidth = 1, title = 'Volume')
plot(volumeSMA, style = plot.style_columns, color = color.new(#8b8ba7, 30), linewidth = 1, title = 'Volume SMA')

// Display time filter headband
if enableTimeFilter and showTimeHeadband
    var table headband = table.new(position.bottom_center, 1, 1, bgcolor = color.new(color.blue, 10), border_width = 1, border_color = color.new(color.blue, 0))

    // Format time strings with leading zeros
    startTimeStr = str.format('{0,number,00}:{1,number,00}', startHour, startMinute)
    endTimeStr = str.format('{0,number,00}:{1,number,00}', endHour, endMinute)

    headbandText = '⏰ Time Filter (NYC): ' + startTimeStr + ' - ' + endTimeStr

    table.cell(headband, 0, 0, headbandText, text_color = color.white, text_size = size.small)

Overview

Volume Historical Patterns computes an SMA of volume using optional time filtering for NYC hours and identifies the highest volume bar ever seen. Bars receive custom colors based on volume relative to this maximum or average thresholds defined by user inputs. This tool highlights volume extremes for spotting unusual activity and provides context through the SMA overlay on the price chart.

Details

Published by

major on GitHub

Type

Indicator, Pine Script v6

Draws

Separate pane below the chart

Category

Volume, Moving averages

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
SMA Lengthint20smaLength
High Volume Multiplierfloat3.0highVolMultiplier
Low Volume Percentagefloat0.5lowVolPercentage
Enable Time FilterboolfalseenableTimeFilter
Start Hour (NYC)int10startHour
Start Minuteint30startMinute
End Hour (NYC)int15endHour
End Minuteint00endMinute
Show Time Filter HeadbandbooltrueshowTimeHeadband
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

Aggregate Signal (v.2)

by capissimo
114 stars

Aggregate Signal (v.2) is an oscillator indicator that combines multiple technical factors into a single composite score. It scales OHLCV data using minimax normalization and evaluates indicators such as MACD, RSI, Stochastic, CCI, Momentum, On-Balance Volume,

Indicator v4 Oscillators & momentumMoving averages Repaints
Updated 1 year ago · None stated GitHub repository of Aggregate Signal (v.2)

Volume-Weighted MACD

by mihakralj
99 stars

This indicator plots a volume-weighted MACD in a separate pane. It subtracts a slow volume-weighted moving average of close from a faster one, then smooths that line with an exponential moving average to form the signal. A column histogram shows the gap betwee

Indicator v5 Oscillators & momentumMoving averages
Updated 4 weeks ago · Apache-2.0 GitHub repository of Volume-Weighted MACD

PPO ATR Bands

by cryptorife
75 stars

PPO ATR Bands plots a percentage price oscillator in a separate pane. It compares a Hull average of typical price with a volume-weighted exponential average of Parabolic SAR, then scales three true-range bands around the slow average into matching oscillator l

Indicator v4 Oscillators & momentumMoving averages
Updated 3 years ago · GPL-3.0 GitHub repository of PPO ATR Bands

RSI-VWMA

by Zettt
43 stars

This indicator calculates the Relative Strength Index using a volume-weighted moving average of the closing price as its source. It plots the resulting oscillator in a separate pane alongside configurable overbought and oversold threshold lines. The plot line

Indicator v4 Oscillators & momentumMoving averages
Updated 1 year ago · None stated GitHub repository of RSI-VWMA

Trap Shorts - Hamza Naveed

by ProfHamzaNaveed
43 stars

This indicator tracks and visualizes cryptocurrency net positioning across multiple derivative exchanges, including Binance, BitMEX, and Kraken. It calculates aggregated net longs, net shorts, net delta, and ratio metrics, or an optional Position RSI, renderin

Indicator v5 VolumeOscillators & momentum
Updated 9 months ago · None stated GitHub repository of Trap Shorts - Hamza Naveed

On Balance Volume

by TWODS-CAPITAL
37 stars

This indicator plots the standard On Balance Volume (OBV) in a separate pane by accumulating volume based on the direction of price changes. It includes an optional smoothing line that can apply a Simple, Exponential, Smoothed, Weighted, or Volume-Weighted Mov

Indicator v5 VolumeMoving averages
Updated 3 years ago · MIT GitHub repository of On Balance Volume

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