Indicator · Pine Script v6 · On the chart

High Volume Momentum Strategy

by lajulajay

An overlay indicator that marks price breaks confirmed by a volume surge.

View on GitHub

Archived by its author

GitHub stars1on the repository
Pine versionv6current
Lines of code266
Settings23inputs
LicenceMIT
Last update1 year ago23 Jul 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

266 lines of Pine Script v6 from high-vol-momentum-strategy.pine, published under MIT. Keep the author's credit and licence lines when you reuse it.

high-vol-momentum-strategy.pine
//@version=6
// High Volume Momentum Strategy
// A Pine Script indicator that detects price breakouts confirmed by volume surges
// and optional technical confirmations (retest, momentum, consolidation).
//
// Features:
// - Volume surge detection with customizable thresholds
// - Price breakout detection with configurable lookback periods
// - Multiple confirmation types: Retest, Momentum (RSI+MACD), Consolidation
// - Market hours filtering (pre-market, regular, after-hours)
// - Fakeout screening with candle size and EMA filters
// - Visual labels with confirmation type indicators
// - Debug labels for troubleshooting
//
// Author: lajulajay
// License: MIT
// Version: 1.0.0

indicator("High Volume Momentum Strategy", overlay=true, max_labels_count=500)

// ============================================================================
// INPUT PARAMETERS
// ============================================================================

// Volume Analysis Settings
volume_lookback_period = input.int(20, "Volume Lookback Period", minval=5, maxval=50, tooltip="Period used for volume baseline calculation")
volume_threshold_pct = input.float(110.0, "Volume Threshold % of Average", minval=50.0, maxval=500.0, step=10.0, tooltip="Percentage of average volume required for break confirmation")
volume_threshold_pct := volume_threshold_pct / 100.0

// Price Break Analysis Settings
price_lookback_period = input.int(12, "Price Lookback Period", minval=5, maxval=50, tooltip="Period used for price break detection")
break_threshold_pct = input.float(0.1, "Price Break Threshold %", minval=0.1, maxval=25.0, step=0.1, tooltip="Percentage above highest high required for break detection")
break_threshold_pct := break_threshold_pct / 100.0
break_direction = input.string("Both", "Break Direction", options=["Up", "Down", "Both"])

// Market Hours Configuration
include_premarket = input.bool(true, "Include Pre-Market")
include_regular = input.bool(true, "Include Regular Hours")
include_afterhours = input.bool(true, "Include After Hours")

// Confirmation Settings
// Momentum Parameters (Free Plan Limits: max 5000 bars)
rsi_length = input.int(14, "RSI Length", minval=1, maxval=50, tooltip="Free plan: max 50 bars")
rsi_bullish_threshold = input.int(50, "RSI Bullish Threshold", minval=30, maxval=70)
rsi_bearish_threshold = input.int(50, "RSI Bearish Threshold", minval=30, maxval=70)

macd_fast = input.int(12, "MACD Fast Length", minval=1, maxval=50, tooltip="Free plan: max 50 bars")
macd_slow = input.int(26, "MACD Slow Length", minval=1, maxval=50, tooltip="Free plan: max 50 bars")
macd_signal = input.int(9, "MACD Signal Length", minval=1, maxval=50, tooltip="Free plan: max 50 bars")

// Consolidation Parameters (Free Plan Limits: max 5000 bars)
consolidation_lookback = input.int(15, "Consolidation Lookback", minval=5, maxval=100, tooltip="Free plan: max 100 bars")
consolidation_threshold = input.float(4.0, "Consolidation Range %", minval=0.5, maxval=10.0, step=0.1, tooltip="Lower values for tighter consolidation detection")
consolidation_threshold := consolidation_threshold / 100.0

// Fakeout Screening Parameters
use_fakeout_screening = input.bool(true, "Use Fakeout Screening", tooltip="Filter out potential fakeouts")
candle_size_multiplier = input.float(1.5, "Candle Size Multiplier", minval=1.0, maxval=5.0, step=0.1, tooltip="Breakout candle must be > X times average range")
use_ema_filter = input.bool(true, "Use 200 EMA Filter", tooltip="Only allow breakouts above 200 EMA")

// Visual Settings
show_labels = input.bool(true, "Show Break Labels")
break_label_info = input.string("R=Retest, M=Momentum, C=Consolidation", "Break Label Legend", tooltip="R = Retest confirmation (price retested support/resistance and held)\nM = Momentum confirmation (RSI + MACD conditions met)\nC = Consolidation confirmation (breakout from consolidation pattern)")
show_debug_labels = input.bool(false, "Show Debug Labels", tooltip="Shows detailed condition status for troubleshooting")
label_size = input.string("Normal", "Label Size", options=["Tiny", "Small", "Normal", "Large"])

// ============================================================================
// MARKET HOURS DETECTION
// ============================================================================

// Use market time (Eastern Time) for session detection
market_time = time
market_time_seconds = market_time % 86400  // Get seconds since midnight

// Apply Eastern Time offset (UTC-5 to convert to ET)
adjusted_seconds = (market_time_seconds - (5 * 3600)) % 86400
if adjusted_seconds < 0
    adjusted_seconds := adjusted_seconds + 86400

// Convert to hours and minutes (Eastern Time)
market_hour = math.floor(adjusted_seconds / 3600)
market_minute = math.floor((adjusted_seconds % 3600) / 60)
market_time_minutes = market_hour * 60 + market_minute

// Define market hours in minutes since midnight (Eastern Time)
premarket_start = 4 * 60    // 4:00 AM ET
premarket_end = 9 * 60 + 30 // 9:30 AM ET
regular_start = 9 * 60 + 30 // 9:30 AM ET
regular_end = 16 * 60       // 4:00 PM ET
afterhours_start = 16 * 60  // 4:00 PM ET
afterhours_end = 20 * 60    // 8:00 PM ET

// Check if current time falls within each session
is_premarket = market_time_minutes >= premarket_start and market_time_minutes < premarket_end
is_regular = market_time_minutes >= regular_start and market_time_minutes < regular_end
is_afterhours = market_time_minutes >= afterhours_start and market_time_minutes < afterhours_end

// Handle times outside normal market hours (extend after hours to cover overnight)
if market_time_minutes >= afterhours_end or market_time_minutes < premarket_start
    is_afterhours := true
is_valid_session = (include_premarket and is_premarket) or 
                   (include_regular and is_regular) or 
                   (include_afterhours and is_afterhours)

// ============================================================================
// VOLUME ANALYSIS
// ============================================================================

// Calculate average volume over volume lookback period
volume_avg = ta.sma(volume, volume_lookback_period)
volume_threshold = volume_avg * volume_threshold_pct

// Check if current volume meets threshold
high_volume = volume >= volume_threshold and is_valid_session

// ============================================================================
// PRICE BREAK ANALYSIS
// ============================================================================

// Breakout condition
price_break_up = close > ta.highest(close[1], 20) * (1 + break_threshold_pct)
price_break_down = close < ta.lowest(close[1], 20) * (1 - break_threshold_pct)

// Volume confirmation
volume_surge = volume > ta.sma(volume, 20) * volume_threshold_pct

// Momentum
momentum_rsi = ta.rsi(close, 14)
[momentum_macd_line, momentum_signal_line, momentum_hist] = ta.macd(close, 12, 26, 9)
momentum_valid = momentum_rsi > 55 or momentum_macd_line > momentum_signal_line

// Retest levels (moved here to avoid circular dependency)
retest_bullish_level = ta.lowest(low, 5)
retest_bearish_level = ta.highest(high, 5)

// Detect retest and hold (simplified - no dependency on previous breaks)
retest_bullish_hold = low <= retest_bullish_level and close > retest_bullish_level
retest_bearish_hold = high >= retest_bearish_level and close < retest_bearish_level

// Consolidation pattern detection (moved here to avoid circular dependency)
consolidation_high = ta.highest(high, consolidation_lookback)
consolidation_low = ta.lowest(low, consolidation_lookback)
consolidation_range = (consolidation_high - consolidation_low) / consolidation_low
in_consolidation = consolidation_range <= consolidation_threshold

// Momentum confirmation (moved here to avoid circular dependency)
momentum_bullish_confirm = momentum_rsi > 55 and momentum_macd_line > momentum_signal_line
momentum_bearish_confirm = momentum_rsi < 45 and momentum_macd_line < momentum_signal_line

// Consolidation confirmation (moved here to avoid circular dependency)
consolidation_bullish_confirm = in_consolidation[1] and not in_consolidation and close > consolidation_high[1]
consolidation_bearish_confirm = in_consolidation[1] and not in_consolidation and close < consolidation_low[1]

// Combined conditions - require volume surge, price break, and at least one confirmation
upward_break = price_break_up and volume_surge and is_valid_session and (retest_bullish_hold or momentum_bullish_confirm or consolidation_bullish_confirm)
downward_break = price_break_down and volume_surge and is_valid_session and (retest_bearish_hold or momentum_bearish_confirm or consolidation_bearish_confirm)

// Determine break direction based on settings
bullish_break = upward_break and (break_direction == "Up" or break_direction == "Both")
bearish_break = downward_break and (break_direction == "Down" or break_direction == "Both")

// ============================================================================
// CONSECUTIVE BREAK TRACKING
// ============================================================================

// Track consecutive breaks to limit labels
var int consecutive_bull_breaks = 0
var int consecutive_bear_breaks = 0

// Reset counters when direction changes
if bullish_break and not bearish_break
    consecutive_bull_breaks := consecutive_bull_breaks + 1
    consecutive_bear_breaks := 0
else if bearish_break and not bullish_break
    consecutive_bear_breaks := consecutive_bear_breaks + 1
    consecutive_bull_breaks := 0
else if not bullish_break and not bearish_break
    consecutive_bull_breaks := 0
    consecutive_bear_breaks := 0

// Only show labels for first 2 consecutive breaks
show_bullish_label = show_labels and bullish_break and consecutive_bull_breaks <= 2
show_bearish_label = show_labels and bearish_break and consecutive_bear_breaks <= 2

// Determine label colors (blue for second consecutive break)
bullish_label_color = consecutive_bull_breaks == 2 ? color.new(color.blue, 0) : color.new(color.green, 0)
bearish_label_color = consecutive_bear_breaks == 2 ? color.new(color.blue, 0) : color.new(color.red, 0)

// Debug output for consecutive break tracking
if show_debug_labels and (bullish_break or bearish_break)
    debug_text = "CONSECUTIVE DEBUG\n" +
                 "Bull Break: " + (bullish_break ? "✓" : "✗") + "\n" +
                 "Bear Break: " + (bearish_break ? "✓" : "✗") + "\n" +
                 "Bull Count: " + str.tostring(consecutive_bull_breaks) + "\n" +
                 "Bear Count: " + str.tostring(consecutive_bear_breaks) + "\n" +
                 "Show Bull: " + (show_bullish_label ? "✓" : "✗") + "\n" +
                 "Show Bear: " + (show_bearish_label ? "✓" : "✗")
    
    label.new(x=bar_index, y=high + (high - low) * 2.5, style=label.style_label_up, 
              color=color.new(color.orange, 0), textcolor=color.white, size=size.small, 
              text=debug_text)

// ============================================================================
// MOMENTUM INDICATORS
// ============================================================================

// RSI
rsi = ta.rsi(close, rsi_length)
rsi_bullish = rsi > rsi_bullish_threshold
rsi_bearish = rsi < rsi_bearish_threshold

// MACD
[macd_line, signal_line, hist] = ta.macd(close, macd_fast, macd_slow, macd_signal)
macd_bullish_cross = ta.crossover(macd_line, signal_line)
macd_bearish_cross = ta.crossunder(macd_line, signal_line)

// ============================================================================
// ALERTS
// ============================================================================

// Break alerts
alertcondition(bullish_break, "Bullish Volume Break", "Bullish volume break detected!")
alertcondition(bearish_break, "Bearish Volume Break", "Bearish volume break detected!")

// ============================================================================
// PLOTTING AND ANNOTATIONS
// ============================================================================

// Plot break levels (using 20-bar high/low as thresholds) - DISABLED
// plot(bullish_break ? ta.highest(close[1], 20) : na, "Bullish Break Level", color=bull_color, linewidth=2)
// plot(bearish_break ? ta.lowest(close[1], 20) : na, "Bearish Break Level", color=bear_color, linewidth=2)



// ============================================================================
// LABELS
// ============================================================================

// Break labels
if show_bullish_label
    vol_k = volume >= 1000 ? str.tostring(volume / 1000, "#.#") + "K" : str.tostring(volume, "#")
    confirm_letters = ""
    confirm_letters := confirm_letters + (retest_bullish_hold ? "R" : "")
    confirm_letters := confirm_letters + (momentum_bullish_confirm ? "M" : "")
    confirm_letters := confirm_letters + (consolidation_bullish_confirm ? "C" : "")
    label.new(x=bar_index, y=low - (high - low) * 1.5, style=label.style_label_down, color=bullish_label_color, textcolor=color.white, size=size.normal, text="↑ BREAK\nVol: " + vol_k + "\nPrice: " + str.tostring(close, "#.##") + "\nTriggers: " + confirm_letters)

if show_bearish_label
    vol_k = volume >= 1000 ? str.tostring(volume / 1000, "#.#") + "K" : str.tostring(volume, "#")
    confirm_letters = ""
    confirm_letters := confirm_letters + (retest_bearish_hold ? "R" : "")
    confirm_letters := confirm_letters + (momentum_bearish_confirm ? "M" : "")
    confirm_letters := confirm_letters + (consolidation_bearish_confirm ? "C" : "")
    label.new(x=bar_index, y=high + (high - low) * 1.5, style=label.style_label_up, color=bearish_label_color, textcolor=color.white, size=size.normal, text="↓ BREAK\nVol: " + vol_k + "\nPrice: " + str.tostring(close, "#.##") + "\nTriggers: " + confirm_letters)

// Debug labels
if show_debug_labels and bar_index % 5 == 0
    // Calculate key values
    vol_ratio = volume / ta.sma(volume, 20)
    price_vs_high = (close / ta.highest(close[1], 20) - 1) * 100
    price_vs_low = (close / ta.lowest(close[1], 20) - 1) * 100
    
    // Build debug text
    debug_text = "DEBUG\n" + str.tostring(price_vs_high, "#.##") + "%\n" + str.tostring(vol_ratio, "#.##") + "x\n" + str.tostring(momentum_rsi, "#")
    
    label.new(x=bar_index, y=high + (high - low) * 1.5, style=label.style_label_up, color=color.new(color.purple, 0), textcolor=color.white, size=size.normal, text="DEBUG\nPrice v Hi: " + str.tostring(price_vs_high, "#.##") + "%\nPrice v Lo: " + str.tostring(price_vs_low, "#.##") + "%\nVol Ratio: " + str.tostring(vol_ratio, "#.##") + "x\nVol ↑: " + (volume_surge ? "✓" : "✗") + "\nSession: " + (is_valid_session ? "✓" : "✗"))

Overview

A break is when price moves past the recent high or low by a set percentage, direction selectable, on volume above its average. Optional confirmations are a retest, RSI and MACD momentum, and consolidation. A fakeout screen checks candle size and a 200 EMA filter. Pre-market, regular and after-hours sessions can be switched on or off. Labels show the break type. Despite its name, it is an indicator with no orders.

Details

Published by

lajulajay on GitHub

Type

Indicator, Pine Script v6

Draws

On the price chart

Category

Breakout, Volume, Oscillators & momentum

Markets

Stocks

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.

Settings

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

SettingTypeDefaultVariable
Volume Lookback Periodint20volume_lookback_period
Volume Threshold % of Averagefloat110.0volume_threshold_pct
Price Lookback Periodint12price_lookback_period
Price Break Threshold %float0.1break_threshold_pct
Break DirectionstringBothbreak_direction
Include Pre-Marketbooltrueinclude_premarket
Include Regular Hoursbooltrueinclude_regular
Include After Hoursbooltrueinclude_afterhours
RSI Lengthint14rsi_length
RSI Bullish Thresholdint50rsi_bullish_threshold
RSI Bearish Thresholdint50rsi_bearish_threshold
MACD Fast Lengthint12macd_fast
Show all 23 settings
SettingTypeDefaultVariable
MACD Slow Lengthint26macd_slow
MACD Signal Lengthint9macd_signal
Consolidation Lookbackint15consolidation_lookback
Consolidation Range %float4.0consolidation_threshold
Use Fakeout Screeningbooltrueuse_fakeout_screening
Candle Size Multiplierfloat1.5candle_size_multiplier
Use 200 EMA Filterbooltrueuse_ema_filter
Show Break Labelsbooltrueshow_labels
Break Label LegendstringR=Retest, M=Momentum, C=Consolidationbreak_label_info
Show Debug Labelsboolfalseshow_debug_labels
Label SizestringNormallabel_size
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

2 stars

This overlay indicator demonstrates TradingView alert configuration. It plots 20- and 50-period simple moving averages and creates alert conditions when price crosses the shorter average or the averages cross each other. It also alerts on RSI crossing 70 or 30

Indicator v6 Moving averagesOscillators & momentum
Updated 2 months ago · MIT GitHub repository of Alert Configuration Examples

Maher Hero Saudi Alerts

by maherhato1986
1 stars

A chart-overlay indicator that scores each bar out of 100 using trend versus the 20 EMA, MACD, RSI range, volume ratio, an early breakout or retest of the prior 20-bar high, distance to the next resistance and an ATR-based stop distance. Hard rejections cap th

Indicator v6 BreakoutOscillators & momentum
Updated 2 months ago · None stated GitHub repository of Maher Hero Saudi Alerts

Squarify 46 v2

by nishpa800
1 stars

Overlay indicator that merges forty-six numbered buy and sell triggers into one study on the price chart. The changelog describes combinations of unified combo, Napalm and Charge engines, Heavy Weapon and Floor patterns, UU, UUU and UUUU streaks, an Omega mark

Indicator v5 BreakoutVolume
Updated 2 months ago · None stated GitHub repository of Squarify 46 v2

VWAP Reclaim Indicator

by skipp-dev
1 stars

This overlay indicator plots an anchored VWAP and marks reclaim setups on the price chart. It can signal a simple VWAP cross or a reclaim, retest, and breakout of a rolling pullback high or low, filtered by trade direction and optional matching VWAP slope. A p

Indicator v6 TrendVolume Repaints
Updated 3 days ago · None stated GitHub repository of VWAP Reclaim Indicator

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

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