1Copy the scriptPress Copy script above, or the copy button on the code below.
2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
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.
The inputs you can change from the gear icon on the chart. Defaults are the author's.
Setting
Type
Default
Variable
Volume Lookback Period
int
20
volume_lookback_period
Volume Threshold % of Average
float
110.0
volume_threshold_pct
Price Lookback Period
int
12
price_lookback_period
Price Break Threshold %
float
0.1
break_threshold_pct
Break Direction
string
Both
break_direction
Include Pre-Market
bool
true
include_premarket
Include Regular Hours
bool
true
include_regular
Include After Hours
bool
true
include_afterhours
RSI Length
int
14
rsi_length
RSI Bullish Threshold
int
50
rsi_bullish_threshold
RSI Bearish Threshold
int
50
rsi_bearish_threshold
MACD Fast Length
int
12
macd_fast
Show all 23 settings
Setting
Type
Default
Variable
MACD Slow Length
int
26
macd_slow
MACD Signal Length
int
9
macd_signal
Consolidation Lookback
int
15
consolidation_lookback
Consolidation Range %
float
4.0
consolidation_threshold
Use Fakeout Screening
bool
true
use_fakeout_screening
Candle Size Multiplier
float
1.5
candle_size_multiplier
Use 200 EMA Filter
bool
true
use_ema_filter
Show Break Labels
bool
true
show_labels
Break Label Legend
string
R=Retest, M=Momentum, C=Consolidation
break_label_info
Show Debug Labels
bool
false
show_debug_labels
Label Size
string
Normal
label_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.
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
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
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
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
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
This overlay indicator marks call and put setups from EMAs, RSI, MACD, and a SPY volume ratio. A call needs higher highs, RSI above its minimum, rising MACD, above-average proxy volume, and a rising trend EMA; a put reverses those tests. Early markers use an E